From 29784de96ea3e340003e4a94290faff40c7d7373 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 21 Feb 2023 22:21:45 +0800 Subject: [PATCH 001/156] fix: only change in logic --- .gitignore | 6 +- contracts/ExternalBribe.sol | 2 +- contracts/InternalBribe.sol | 11 ++- contracts/Minter.sol | 15 ++-- contracts/Pair.sol | 76 +++++++++++++++---- contracts/RewardsDistributor.sol | 4 +- contracts/Router.sol | 2 +- contracts/Velo.sol | 7 +- contracts/Voter.sol | 21 ++++- contracts/WrappedExternalBribe.sol | 2 +- contracts/factories/PairFactory.sol | 46 +++++++++-- .../factories/WrappedExternalBribeFactory.sol | 13 ++-- .../IWrappedExternalBribeFactory.sol | 5 ++ 13 files changed, 159 insertions(+), 51 deletions(-) create mode 100644 contracts/interfaces/IWrappedExternalBribeFactory.sol diff --git a/.gitignore b/.gitignore index 323a3d12..5a6eae14 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,8 @@ abi build scripts/xbribes # for verify -Flattened.sol \ No newline at end of file +Flattened.sol +lib/openzeppelin-contracts +lib/forge-std +lib/LayerZero +lib/forge-std \ No newline at end of file diff --git a/contracts/ExternalBribe.sol b/contracts/ExternalBribe.sol index e7bfe393..9161e292 100644 --- a/contracts/ExternalBribe.sol +++ b/contracts/ExternalBribe.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import "openzeppelin-contracts/contracts/utils/math/Math.sol"; import 'contracts/interfaces/IBribe.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IGauge.sol'; diff --git a/contracts/InternalBribe.sol b/contracts/InternalBribe.sol index cae81540..ac00876c 100644 --- a/contracts/InternalBribe.sol +++ b/contracts/InternalBribe.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IBribe.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IVoter.sol'; @@ -14,7 +14,6 @@ contract InternalBribe is IBribe { address public immutable _ve; uint public constant DURATION = 7 days; // rewards are released over 7 days - uint public constant PRECISION = 10 ** 18; uint internal constant MAX_REWARD_TOKENS = 16; // default snx staking contract implementation @@ -271,7 +270,7 @@ contract InternalBribe is IBribe { if (totalSupply == 0) { return rewardPerTokenStored[token]; } - return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * PRECISION / totalSupply); + return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * 10**IERC20(token).decimals() / totalSupply); } function batchRewardPerToken(address token, uint maxRuns) external { @@ -309,7 +308,7 @@ contract InternalBribe is IBribe { function _calcRewardPerToken(address token, uint timestamp1, uint timestamp0, uint supply, uint startTimestamp) internal view returns (uint, uint) { uint endTime = Math.max(timestamp1, startTimestamp); - return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * PRECISION / supply), endTime); + return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * 10**IERC20(token).decimals() / supply), endTime); } /// @dev Update stored rewardPerToken values without the last one snapshot @@ -384,13 +383,13 @@ contract InternalBribe is IBribe { Checkpoint memory cp1 = checkpoints[tokenId][i+1]; (uint _rewardPerTokenStored0,) = getPriorRewardPerToken(token, cp0.timestamp); (uint _rewardPerTokenStored1,) = getPriorRewardPerToken(token, cp1.timestamp); - reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / PRECISION; + reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / 10**IERC20(token).decimals(); } } Checkpoint memory cp = checkpoints[tokenId][_endIndex]; (uint _rewardPerTokenStored,) = getPriorRewardPerToken(token, cp.timestamp); - reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][tokenId])) / PRECISION; + reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][tokenId])) / 10**IERC20(token).decimals(); return reward; } diff --git a/contracts/Minter.sol b/contracts/Minter.sol index 75d476fb..dd913758 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -1,7 +1,8 @@ -// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import "contracts/libraries/Math.sol"; +import "openzeppelin-contracts/contracts/utils/math/Math.sol"; + import "contracts/interfaces/IMinter.sol"; import "contracts/interfaces/IRewardsDistributor.sol"; import "contracts/interfaces/IVelo.sol"; @@ -19,7 +20,7 @@ contract Minter is IMinter { IVoter public immutable _voter; IVotingEscrow public immutable _ve; IRewardsDistributor public immutable _rewards_distributor; - uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M VELO (VELO has 18 decimals) + uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M VELO (VELOhas 18 decimals) uint public active_period; uint internal constant LOCK = 86400 * 7 * 52 * 4; @@ -27,7 +28,7 @@ contract Minter is IMinter { address public team; address public pendingTeam; uint public teamRate; - uint public constant MAX_TEAM_RATE = 50; // 50 bps = 0.05% + uint public constant MAX_TEAM_RATE = 50; // 5% max event Mint(address indexed sender, uint weekly, uint circulating_supply, uint circulating_emission); @@ -38,7 +39,7 @@ contract Minter is IMinter { ) { initializer = msg.sender; team = msg.sender; - teamRate = 30; // 30 bps = 0.03% + teamRate = 30; // 30 bps = 3% _velo = IVelo(IVotingEscrow(__ve).token()); _voter = IVoter(__voter); _ve = IVotingEscrow(__ve); @@ -47,8 +48,8 @@ contract Minter is IMinter { } function initialize( - address[] memory claimants, - uint[] memory amounts, + address[] memory claimants, // partnerAddrs + uint[] memory amounts, // partnerAmounts uint max // sum amounts / max = % ownership of top protocols, so if initial 20m is distributed, and target is 25% protocol ownership, then max - 4 x 20m = 80m ) external { require(initializer == msg.sender); diff --git a/contracts/Pair.sol b/contracts/Pair.sol index fc33938f..73640cd6 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -1,13 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IPair.sol'; import 'contracts/interfaces/IPairCallee.sol'; import 'contracts/factories/PairFactory.sol'; import 'contracts/PairFees.sol'; +import 'contracts/interfaces/IBribe.sol'; + // The base pair of pools, either stable or volatile contract Pair is IPair { @@ -34,6 +36,10 @@ contract Pair is IPair { address public immutable token1; address public immutable fees; address immutable factory; + address public externalBribe; + address public voter; + address public immutable tank; + bool public hasGauge; // Structure to capture time period obervations every 30 minutes, used for local oracles struct Observation { @@ -71,6 +77,8 @@ contract Pair is IPair { mapping(address => uint) public claimable1; event Fees(address indexed sender, uint amount0, uint amount1); + event TankFees(address indexed token, uint amount0, address tank); + event GaugeFees(address indexed token, uint amount0, address externalBribe); event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( @@ -89,7 +97,9 @@ contract Pair is IPair { constructor() { factory = msg.sender; - (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); + voter = PairFactory(msg.sender).voter(); // nice easy way to add the voter :) we already getting this from pair factory tho + tank = PairFactory(msg.sender).tank(); // nice easy way to add the voter :) we already getting this from pair factory tho + (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); //wondering why msg.sender is passed here?? (token0, token1, stable) = (_token0, _token1, _stable); fees = address(new PairFees(_token0, _token1)); if (_stable) { @@ -115,6 +125,24 @@ contract Pair is IPair { _unlocked = 1; } + function _safeApprove(address token, address spender, uint value) internal { + require(token.code.length > 0); + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, value)); + require(success && (data.length == 0 || abi.decode(data, (bool)))); + } + + function setExternalBribe(address _externalBribe) external { + require(msg.sender == voter, 'Only voter can set external bribe'); + externalBribe = _externalBribe; + _safeApprove(token0, externalBribe, type(uint).max); + _safeApprove(token1, externalBribe, type(uint).max); + } + + function setHasGauge(bool value) external { + require(msg.sender == voter, 'Only voter can set has gauge'); + hasGauge = value; + } + function observationLength() external view returns (uint) { return observations.length; } @@ -148,24 +176,46 @@ contract Pair is IPair { } } - // Accrue fees on token0 + // Accrue fees on token0. function _update0(uint amount) internal { - _safeTransfer(token0, fees, amount); // transfer the fees out to PairFees - uint256 _ratio = amount * 1e18 / totalSupply; // 1e18 adjustment is removed during claim - if (_ratio > 0) { - index0 += _ratio; + if (hasGauge == false) { + _safeTransfer(token0, tank, amount); // transfer the fees to tank MSig for gaugeless LPs + uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim + if (_ratio > 0) { + index0 += _ratio; + } + emit TankFees(token0, amount, tank); + } + if (hasGauge == true) { + // _safeApprove(token0, externalBribe, amount); // max abprove when setExternalBribe() is called + IBribe(externalBribe).notifyRewardAmount(token0, amount); //transfer fees to exBribes + // _safeTransfer(token0, tank, amount); + uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim + if (_ratio > 0) { + index0 += _ratio; + } + emit GaugeFees(token0, amount, externalBribe); } - emit Fees(msg.sender, amount, 0); } // Accrue fees on token1 function _update1(uint amount) internal { - _safeTransfer(token1, fees, amount); - uint256 _ratio = amount * 1e18 / totalSupply; - if (_ratio > 0) { - index1 += _ratio; + if (hasGauge == false) { + _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs + uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim + if (_ratio > 0) { + index0 += _ratio; + } + emit TankFees(token1, amount, tank); + } + if (hasGauge == true) { + IBribe(externalBribe).notifyRewardAmount(token1, amount); //transfer fees to exBribes + uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim + if (_ratio > 0) { + index0 += _ratio; + } + emit GaugeFees(token1, amount, externalBribe); } - emit Fees(msg.sender, 0, amount); } // this function MUST be called on any balance changes, otherwise can be used to infinitely claim fees diff --git a/contracts/RewardsDistributor.sol b/contracts/RewardsDistributor.sol index 0ad5bac6..3fc74bce 100644 --- a/contracts/RewardsDistributor.sol +++ b/contracts/RewardsDistributor.sol @@ -1,7 +1,7 @@ -// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IRewardsDistributor.sol'; import 'contracts/interfaces/IVotingEscrow.sol'; diff --git a/contracts/Router.sol b/contracts/Router.sol index c6866d27..46efa97c 100644 --- a/contracts/Router.sol +++ b/contracts/Router.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IPair.sol'; import 'contracts/interfaces/IPairFactory.sol'; diff --git a/contracts/Velo.sol b/contracts/Velo.sol index 47cd3382..b7e3c839 100644 --- a/contracts/Velo.sol +++ b/contracts/Velo.sol @@ -42,14 +42,11 @@ contract Velo is IVelo { merkleClaim = _merkleClaim; } - // Initial mint: total 82M - // 4M for "Genesis" pools - // 30M for liquid team allocation (40M excl init veNFT) - // 48M for future partners + // NFTs are minted from this amount as well now function initialMint(address _recipient) external { require(msg.sender == minter && !initialMinted); initialMinted = true; - _mint(_recipient, 82 * 1e6 * 1e18); + _mint(_recipient, 400 * 1e6 * 1e18); //#settings } function approve(address _spender, uint _value) external returns (bool) { diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 9f086005..e5e09352 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IBribe.sol'; import 'contracts/interfaces/IBribeFactory.sol'; import 'contracts/interfaces/IGauge.sol'; @@ -13,6 +13,10 @@ import 'contracts/interfaces/IPairFactory.sol'; import 'contracts/interfaces/IVoter.sol'; import 'contracts/interfaces/IVotingEscrow.sol'; +import 'contracts/Pair.sol'; + +import 'contracts/interfaces/IWrappedExternalBribeFactory.sol'; + contract Voter is IVoter { address public immutable _ve; // the ve token that governs these contracts @@ -20,6 +24,7 @@ contract Voter is IVoter { address internal immutable base; address public immutable gaugefactory; address public immutable bribefactory; + address public immutable wrappedxbribefactory; // this is the address of the wrapped external bribe factory uint internal constant DURATION = 7 days; // rewards are released over 7 days address public minter; address public governor; // should be set to an IGovernor @@ -54,12 +59,13 @@ contract Voter is IVoter { event Detach(address indexed owner, address indexed gauge, uint tokenId); event Whitelisted(address indexed whitelister, address indexed token); - constructor(address __ve, address _factory, address _gauges, address _bribes) { + constructor(address __ve, address _factory, address _gauges, address _bribes, address _wrappedxbribefactory) { _ve = __ve; factory = _factory; base = IVotingEscrow(__ve).token(); gaugefactory = _gauges; bribefactory = _bribes; + wrappedxbribefactory = _wrappedxbribefactory; minter = msg.sender; governor = msg.sender; emergencyCouncil = msg.sender; @@ -67,6 +73,7 @@ contract Voter is IVoter { // simple re-entrancy check uint internal _unlocked = 1; + modifier lock() { require(_unlocked == 1); _unlocked = 2; @@ -133,7 +140,10 @@ contract Voter is IVoter { delete poolVote[_tokenId]; } + // remove poke function + function poke(uint _tokenId) external { + require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, _tokenId) || msg.sender == governor); address[] memory _poolVote = poolVote[_tokenId]; uint _poolCnt = _poolVote.length; uint256[] memory _weights = new uint256[](_poolCnt); @@ -215,7 +225,7 @@ contract Voter is IVoter { allowedRewards[1] = tokenB; internalRewards[0] = tokenA; internalRewards[1] = tokenB; - + // if one of the tokens is not base (FLOW) then add base(FLOW) to allowed rewards if (base != tokenA && base != tokenB) { allowedRewards[2] = base; } @@ -228,6 +238,7 @@ contract Voter is IVoter { address _internal_bribe = IBribeFactory(bribefactory).createInternalBribe(internalRewards); address _external_bribe = IBribeFactory(bribefactory).createExternalBribe(allowedRewards); + address _wxbribe = IWrappedExternalBribeFactory(wrappedxbribefactory).createBribe(_external_bribe); address _gauge = IGaugeFactory(gaugefactory).createGauge(_pool, _internal_bribe, _external_bribe, _ve, isPair, allowedRewards); IERC20(base).approve(_gauge, type(uint).max); @@ -239,7 +250,9 @@ contract Voter is IVoter { isAlive[_gauge] = true; _updateFor(_gauge); pools.push(_pool); - emit GaugeCreated(_gauge, msg.sender, _internal_bribe, _external_bribe, _pool); + Pair(_pool).setHasGauge(true); // may need to switch to IPair? + Pair(_pool).setExternalBribe(_wxbribe); // Changed this to wrapped external bribe from + emit GaugeCreated(_gauge, msg.sender, _internal_bribe, _external_bribe, _wxbribe, _pool); return _gauge; } diff --git a/contracts/WrappedExternalBribe.sol b/contracts/WrappedExternalBribe.sol index 9017f9a3..d784f885 100644 --- a/contracts/WrappedExternalBribe.sol +++ b/contracts/WrappedExternalBribe.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/ExternalBribe.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IGauge.sol'; diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 752324e9..714057bd 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -10,11 +10,17 @@ contract PairFactory is IPairFactory { address public pauser; address public pendingPauser; - uint256 public stableFee; - uint256 public volatileFee; - uint256 public constant MAX_FEE = 5; // 0.05% + uint public stableFee; + uint public volatileFee; + uint public constant MAX_FEE = 50; // 0.5% address public feeManager; address public pendingFeeManager; + address public voter; + address public team; + bool internal initial_voter_set; + bool internal initial_tank_set; + address public tank; + address public deployer; mapping(address => mapping(address => mapping(bool => address))) public getPair; address[] public allPairs; @@ -30,8 +36,38 @@ contract PairFactory is IPairFactory { pauser = msg.sender; isPaused = false; feeManager = msg.sender; - stableFee = 2; // 0.02% - volatileFee = 2; + stableFee = 3; // 0.03% + volatileFee = 25; // 0.25% + deployer = msg.sender; + } + + function setTeam(address _team) external { + require(msg.sender == deployer); // might need to set this to deployer?? or just make it + require(team == address(0), 'The team has already been set.'); + team = _team; + } + + function setVoter(address _voter) external { + require(!initial_voter_set, 'The voter has already been set.'); + require(msg.sender == deployer); // have to make sure that this can be set to the voter addres during init script + voter = _voter; + initial_voter_set = true; + } + + function setTank(address _tank) external { + require(!initial_tank_set, 'The tank has already been set.'); + require(msg.sender == deployer); // this should be updateable to team but adding deployer so that init script can run.. + tank = _tank; + initial_tank_set = true; + } + + function acceptTank(address _tank) external { + require(msg.sender == team, 'not pending team'); + tank = _tank; + } + + function getVoter() external view returns (address) { + return voter; } function allPairsLength() external view returns (uint) { diff --git a/contracts/factories/WrappedExternalBribeFactory.sol b/contracts/factories/WrappedExternalBribeFactory.sol index a0299407..9df4d6a5 100644 --- a/contracts/factories/WrappedExternalBribeFactory.sol +++ b/contracts/factories/WrappedExternalBribeFactory.sol @@ -4,14 +4,11 @@ pragma solidity 0.8.13; import {WrappedExternalBribe} from 'contracts/WrappedExternalBribe.sol'; contract WrappedExternalBribeFactory { - address public immutable voter; + bool internal _initialized; + address public voter; mapping(address => address) public oldBribeToNew; address public last_bribe; - constructor(address _voter) { - voter = _voter; - } - function createBribe(address existing_bribe) external returns (address) { require( oldBribeToNew[existing_bribe] == address(0), @@ -21,4 +18,10 @@ contract WrappedExternalBribeFactory { oldBribeToNew[existing_bribe] = last_bribe; return last_bribe; } + + function setVoter(address _voter) external { + require(!_initialized, "Already initialized"); + voter = _voter; + _initialized = true; + } } diff --git a/contracts/interfaces/IWrappedExternalBribeFactory.sol b/contracts/interfaces/IWrappedExternalBribeFactory.sol new file mode 100644 index 00000000..9bf5b3b6 --- /dev/null +++ b/contracts/interfaces/IWrappedExternalBribeFactory.sol @@ -0,0 +1,5 @@ +pragma solidity 0.8.13; + +interface IWrappedExternalBribeFactory { + function createBribe(address) external returns (address); +} From b03099a2b517f01141f18f6f85d016633d4b95cb Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:34:03 +0800 Subject: [PATCH 002/156] fix: fix _update1 in Pair.sol --- contracts/Pair.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 73640cd6..4459eaa3 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -204,7 +204,7 @@ contract Pair is IPair { _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { - index0 += _ratio; + index1 += _ratio; } emit TankFees(token1, amount, tank); } @@ -212,7 +212,7 @@ contract Pair is IPair { IBribe(externalBribe).notifyRewardAmount(token1, amount); //transfer fees to exBribes uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { - index0 += _ratio; + index1 += _ratio; } emit GaugeFees(token1, amount, externalBribe); } From d697c98a2cd173bfb727862b8b926630be3bf6ab Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:38:49 +0800 Subject: [PATCH 003/156] fix: fix if/else in _update0 & _update1 in Pair.sol --- contracts/Pair.sol | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 4459eaa3..b167c3fc 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -178,15 +178,14 @@ contract Pair is IPair { // Accrue fees on token0. function _update0(uint amount) internal { - if (hasGauge == false) { + if (!hasGauge) { _safeTransfer(token0, tank, amount); // transfer the fees to tank MSig for gaugeless LPs uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { index0 += _ratio; } emit TankFees(token0, amount, tank); - } - if (hasGauge == true) { + } else { // _safeApprove(token0, externalBribe, amount); // max abprove when setExternalBribe() is called IBribe(externalBribe).notifyRewardAmount(token0, amount); //transfer fees to exBribes // _safeTransfer(token0, tank, amount); @@ -200,15 +199,14 @@ contract Pair is IPair { // Accrue fees on token1 function _update1(uint amount) internal { - if (hasGauge == false) { + if (!hasGauge) { _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { index1 += _ratio; } emit TankFees(token1, amount, tank); - } - if (hasGauge == true) { + } else { IBribe(externalBribe).notifyRewardAmount(token1, amount); //transfer fees to exBribes uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { From acb79f3c50cbe04300931028ac31e57d4027333c Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:40:02 +0800 Subject: [PATCH 004/156] chore: fix comments --- contracts/Minter.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/Minter.sol b/contracts/Minter.sol index dd913758..c1034614 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -20,7 +20,7 @@ contract Minter is IMinter { IVoter public immutable _voter; IVotingEscrow public immutable _ve; IRewardsDistributor public immutable _rewards_distributor; - uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M VELO (VELOhas 18 decimals) + uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M VELO (VELO has 18 decimals) uint public active_period; uint internal constant LOCK = 86400 * 7 * 52 * 4; From 877259c82726f0ddfd132b57169dcbec6d13f8d3 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:41:05 +0800 Subject: [PATCH 005/156] fix: fix type uint -> uint256 --- contracts/factories/PairFactory.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 714057bd..c8d1b3bd 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -10,9 +10,9 @@ contract PairFactory is IPairFactory { address public pauser; address public pendingPauser; - uint public stableFee; - uint public volatileFee; - uint public constant MAX_FEE = 50; // 0.5% + uint256 public stableFee; + uint256 public volatileFee; + uint256 public constant MAX_FEE = 50; // 0.5% address public feeManager; address public pendingFeeManager; address public voter; From 95d39c5ac30ccab14962d434485e162d0f632558 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:43:45 +0800 Subject: [PATCH 006/156] fix: remove getVoter function in PairFactory --- contracts/factories/PairFactory.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index c8d1b3bd..de57e4fc 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -66,10 +66,6 @@ contract PairFactory is IPairFactory { tank = _tank; } - function getVoter() external view returns (address) { - return voter; - } - function allPairsLength() external view returns (uint) { return allPairs.length; } From 519b9fc231dad72a5701d665a08adb76319e546b Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:53:58 +0800 Subject: [PATCH 007/156] fix: remove initial_voter_set and initial_tank_set flag in PairFactory --- contracts/factories/PairFactory.sol | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index de57e4fc..6e157449 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -17,8 +17,6 @@ contract PairFactory is IPairFactory { address public pendingFeeManager; address public voter; address public team; - bool internal initial_voter_set; - bool internal initial_tank_set; address public tank; address public deployer; @@ -42,27 +40,19 @@ contract PairFactory is IPairFactory { } function setTeam(address _team) external { - require(msg.sender == deployer); // might need to set this to deployer?? or just make it require(team == address(0), 'The team has already been set.'); + require(msg.sender == deployer, 'Not authorised to set team.'); // might need to set this to deployer?? or just make it team = _team; } function setVoter(address _voter) external { - require(!initial_voter_set, 'The voter has already been set.'); - require(msg.sender == deployer); // have to make sure that this can be set to the voter addres during init script + require(voter == address(0), 'The voter has already been set.'); + require(msg.sender == deployer, 'Not authorised to set voter.'); // have to make sure that this can be set to the voter addres during init script voter = _voter; - initial_voter_set = true; } function setTank(address _tank) external { - require(!initial_tank_set, 'The tank has already been set.'); - require(msg.sender == deployer); // this should be updateable to team but adding deployer so that init script can run.. - tank = _tank; - initial_tank_set = true; - } - - function acceptTank(address _tank) external { - require(msg.sender == team, 'not pending team'); + require(msg.sender == deployer || msg.sender == team, 'Not authorised to set tank.'); // this should be updateable to team but adding deployer so that init script can run.. tank = _tank; } From 73005d89c9811813c23d871a64e8d056689fd9a0 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:56:44 +0800 Subject: [PATCH 008/156] fix: remove initalized flag in WrappedExternalBribeFactory --- contracts/factories/WrappedExternalBribeFactory.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/factories/WrappedExternalBribeFactory.sol b/contracts/factories/WrappedExternalBribeFactory.sol index 9df4d6a5..51374e04 100644 --- a/contracts/factories/WrappedExternalBribeFactory.sol +++ b/contracts/factories/WrappedExternalBribeFactory.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.13; import {WrappedExternalBribe} from 'contracts/WrappedExternalBribe.sol'; contract WrappedExternalBribeFactory { - bool internal _initialized; address public voter; mapping(address => address) public oldBribeToNew; address public last_bribe; @@ -20,8 +19,7 @@ contract WrappedExternalBribeFactory { } function setVoter(address _voter) external { - require(!_initialized, "Already initialized"); + require(voter == address(0), "Already initialized"); voter = _voter; - _initialized = true; } } From 83e44edd895802fd41e838b6533dde15ff03857f Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:57:46 +0800 Subject: [PATCH 009/156] fix: rename wrappedxbribefactory variable in Voter.sol --- contracts/Voter.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index e5e09352..2bab1262 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -24,7 +24,7 @@ contract Voter is IVoter { address internal immutable base; address public immutable gaugefactory; address public immutable bribefactory; - address public immutable wrappedxbribefactory; // this is the address of the wrapped external bribe factory + address public immutable wrappedExternalBribeFactory; // this is the address of the wrapped external bribe factory uint internal constant DURATION = 7 days; // rewards are released over 7 days address public minter; address public governor; // should be set to an IGovernor @@ -59,13 +59,13 @@ contract Voter is IVoter { event Detach(address indexed owner, address indexed gauge, uint tokenId); event Whitelisted(address indexed whitelister, address indexed token); - constructor(address __ve, address _factory, address _gauges, address _bribes, address _wrappedxbribefactory) { + constructor(address __ve, address _factory, address _gauges, address _bribes, address _wrappedExternalBribeFactory) { _ve = __ve; factory = _factory; base = IVotingEscrow(__ve).token(); gaugefactory = _gauges; bribefactory = _bribes; - wrappedxbribefactory = _wrappedxbribefactory; + wrappedExternalBribeFactory = _wrappedExternalBribeFactory; minter = msg.sender; governor = msg.sender; emergencyCouncil = msg.sender; @@ -238,7 +238,7 @@ contract Voter is IVoter { address _internal_bribe = IBribeFactory(bribefactory).createInternalBribe(internalRewards); address _external_bribe = IBribeFactory(bribefactory).createExternalBribe(allowedRewards); - address _wxbribe = IWrappedExternalBribeFactory(wrappedxbribefactory).createBribe(_external_bribe); + address _wxbribe = IWrappedExternalBribeFactory(wrappedExternalBribeFactory).createBribe(_external_bribe); address _gauge = IGaugeFactory(gaugefactory).createGauge(_pool, _internal_bribe, _external_bribe, _ve, isPair, allowedRewards); IERC20(base).approve(_gauge, type(uint).max); From 783ad5f228c68863ec0a230310eacbb220e63db2 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 14:58:44 +0800 Subject: [PATCH 010/156] chore: remove comments --- contracts/Voter.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 2bab1262..eed93d67 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -140,8 +140,6 @@ contract Voter is IVoter { delete poolVote[_tokenId]; } - // remove poke function - function poke(uint _tokenId) external { require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, _tokenId) || msg.sender == governor); address[] memory _poolVote = poolVote[_tokenId]; From 5ac59e3dab13180bdd60cb8e0058cb5d752ea42d Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:03:50 +0800 Subject: [PATCH 011/156] fix: use IPair interface in Voter instead of Pair contract to call functions --- contracts/Voter.sol | 6 ++---- contracts/interfaces/IPair.sol | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index eed93d67..dbc769e8 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -13,8 +13,6 @@ import 'contracts/interfaces/IPairFactory.sol'; import 'contracts/interfaces/IVoter.sol'; import 'contracts/interfaces/IVotingEscrow.sol'; -import 'contracts/Pair.sol'; - import 'contracts/interfaces/IWrappedExternalBribeFactory.sol'; contract Voter is IVoter { @@ -248,8 +246,8 @@ contract Voter is IVoter { isAlive[_gauge] = true; _updateFor(_gauge); pools.push(_pool); - Pair(_pool).setHasGauge(true); // may need to switch to IPair? - Pair(_pool).setExternalBribe(_wxbribe); // Changed this to wrapped external bribe from + IPair(_pool).setHasGauge(true); // may need to switch to IPair? + IPair(_pool).setExternalBribe(_wxbribe); // Changed this to wrapped external bribe from emit GaugeCreated(_gauge, msg.sender, _internal_bribe, _external_bribe, _wxbribe, _pool); return _gauge; } diff --git a/contracts/interfaces/IPair.sol b/contracts/interfaces/IPair.sol index e1af5708..0503a59e 100644 --- a/contracts/interfaces/IPair.sol +++ b/contracts/interfaces/IPair.sol @@ -11,4 +11,6 @@ interface IPair { function mint(address to) external returns (uint liquidity); function getReserves() external view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast); function getAmountOut(uint, address) external view returns (uint); + function setHasGauge(bool value) external; + function setExternalBribe(address _externalBribe) external; } From 02d6e9c01b35a1e20acd35ce52bc7bb4531fdc0a Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:04:29 +0800 Subject: [PATCH 012/156] chore: remove comment --- contracts/Pair.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index b167c3fc..440270d8 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -99,7 +99,7 @@ contract Pair is IPair { factory = msg.sender; voter = PairFactory(msg.sender).voter(); // nice easy way to add the voter :) we already getting this from pair factory tho tank = PairFactory(msg.sender).tank(); // nice easy way to add the voter :) we already getting this from pair factory tho - (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); //wondering why msg.sender is passed here?? + (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); fees = address(new PairFees(_token0, _token1)); if (_stable) { From 1f6952c20bb81bbf4b04581c3d236a39d60ecb37 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:05:05 +0800 Subject: [PATCH 013/156] chore: remove comment --- contracts/Pair.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 440270d8..ed5f5d49 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -97,8 +97,8 @@ contract Pair is IPair { constructor() { factory = msg.sender; - voter = PairFactory(msg.sender).voter(); // nice easy way to add the voter :) we already getting this from pair factory tho - tank = PairFactory(msg.sender).tank(); // nice easy way to add the voter :) we already getting this from pair factory tho + voter = PairFactory(msg.sender).voter(); + tank = PairFactory(msg.sender).tank(); (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); fees = address(new PairFees(_token0, _token1)); From da8309923b401cebb492df2193aa06666bcc2f3f Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:09:00 +0800 Subject: [PATCH 014/156] fix: can only set external bribe once in Pair.sol --- contracts/Pair.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index ed5f5d49..8b888677 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -132,6 +132,7 @@ contract Pair is IPair { } function setExternalBribe(address _externalBribe) external { + require(externalBribe == address(0), 'External bribe has already been set.'); require(msg.sender == voter, 'Only voter can set external bribe'); externalBribe = _externalBribe; _safeApprove(token0, externalBribe, type(uint).max); From 49a7b459d70db3b5591bcbd87013dcd3de2eba87 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:10:28 +0800 Subject: [PATCH 015/156] chore: remove commented code --- contracts/Pair.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 8b888677..2cc23912 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -187,9 +187,7 @@ contract Pair is IPair { } emit TankFees(token0, amount, tank); } else { - // _safeApprove(token0, externalBribe, amount); // max abprove when setExternalBribe() is called IBribe(externalBribe).notifyRewardAmount(token0, amount); //transfer fees to exBribes - // _safeTransfer(token0, tank, amount); uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim if (_ratio > 0) { index0 += _ratio; From 36a57bf0f7f00b946a83a80c96b8b966b7f6eed7 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:15:41 +0800 Subject: [PATCH 016/156] fix: remove index tracking in Pair --- contracts/Pair.sol | 78 ---------------------------------------------- 1 file changed, 78 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 2cc23912..5438fdb9 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -63,19 +63,6 @@ contract Pair is IPair { uint public reserve0CumulativeLast; uint public reserve1CumulativeLast; - // index0 and index1 are used to accumulate fees, this is split out from normal trades to keep the swap "clean" - // this further allows LP holders to easily claim fees for tokens they have/staked - uint public index0 = 0; - uint public index1 = 0; - - // position assigned to each LP to track their current index0 & index1 vs the global position - mapping(address => uint) public supplyIndex0; - mapping(address => uint) public supplyIndex1; - - // tracks the amount of unclaimed, but claimable tokens off of fees for token0 and token1 - mapping(address => uint) public claimable0; - mapping(address => uint) public claimable1; - event Fees(address indexed sender, uint amount0, uint amount1); event TankFees(address indexed token, uint amount0, address tank); event GaugeFees(address indexed token, uint amount0, address externalBribe); @@ -160,38 +147,13 @@ contract Pair is IPair { return (token0, token1); } - // claim accumulated but unclaimed fees (viewable via claimable0 and claimable1) - function claimFees() external returns (uint claimed0, uint claimed1) { - _updateFor(msg.sender); - - claimed0 = claimable0[msg.sender]; - claimed1 = claimable1[msg.sender]; - - if (claimed0 > 0 || claimed1 > 0) { - claimable0[msg.sender] = 0; - claimable1[msg.sender] = 0; - - PairFees(fees).claimFeesFor(msg.sender, claimed0, claimed1); - - emit Claim(msg.sender, msg.sender, claimed0, claimed1); - } - } - // Accrue fees on token0. function _update0(uint amount) internal { if (!hasGauge) { _safeTransfer(token0, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim - if (_ratio > 0) { - index0 += _ratio; - } emit TankFees(token0, amount, tank); } else { IBribe(externalBribe).notifyRewardAmount(token0, amount); //transfer fees to exBribes - uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim - if (_ratio > 0) { - index0 += _ratio; - } emit GaugeFees(token0, amount, externalBribe); } } @@ -200,48 +162,13 @@ contract Pair is IPair { function _update1(uint amount) internal { if (!hasGauge) { _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim - if (_ratio > 0) { - index1 += _ratio; - } emit TankFees(token1, amount, tank); } else { IBribe(externalBribe).notifyRewardAmount(token1, amount); //transfer fees to exBribes - uint _ratio = (amount * 1e18) / totalSupply; // 1e18 adjustment is removed during claim - if (_ratio > 0) { - index1 += _ratio; - } emit GaugeFees(token1, amount, externalBribe); } } - // this function MUST be called on any balance changes, otherwise can be used to infinitely claim fees - // Fees are segregated from core funds, so fees can never put liquidity at risk - function _updateFor(address recipient) internal { - uint _supplied = balanceOf[recipient]; // get LP balance of `recipient` - if (_supplied > 0) { - uint _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient - uint _supplyIndex1 = supplyIndex1[recipient]; - uint _index0 = index0; // get global index0 for accumulated fees - uint _index1 = index1; - supplyIndex0[recipient] = _index0; // update user current position to global position - supplyIndex1[recipient] = _index1; - uint _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued - uint _delta1 = _index1 - _supplyIndex1; - if (_delta0 > 0) { - uint _share = _supplied * _delta0 / 1e18; // add accrued difference for each supplied token - claimable0[recipient] += _share; - } - if (_delta1 > 0) { - uint _share = _supplied * _delta1 / 1e18; - claimable1[recipient] += _share; - } - } else { - supplyIndex0[recipient] = index0; // new users are set to the default global state - supplyIndex1[recipient] = index1; - } - } - function getReserves() public view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast) { _reserve0 = reserve0; _reserve1 = reserve1; @@ -494,14 +421,12 @@ contract Pair is IPair { } function _mint(address dst, uint amount) internal { - _updateFor(dst); // balances must be updated on mint/burn/transfer totalSupply += amount; balanceOf[dst] += amount; emit Transfer(address(0), dst, amount); } function _burn(address dst, uint amount) internal { - _updateFor(dst); totalSupply -= amount; balanceOf[dst] -= amount; emit Transfer(dst, address(0), amount); @@ -560,9 +485,6 @@ contract Pair is IPair { } function _transferTokens(address src, address dst, uint amount) internal { - _updateFor(src); // update fee position for src - _updateFor(dst); // update fee position for dst - balanceOf[src] -= amount; balanceOf[dst] += amount; From 4c9932691d0a905cce05b6595c14cf5fb60baac0 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:16:29 +0800 Subject: [PATCH 017/156] fix: remove claim event in Pair --- contracts/Pair.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 5438fdb9..af7494d4 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -77,7 +77,6 @@ contract Pair is IPair { address indexed to ); event Sync(uint reserve0, uint reserve1); - event Claim(address indexed sender, address indexed recipient, uint amount0, uint amount1); event Transfer(address indexed from, address indexed to, uint amount); event Approval(address indexed owner, address indexed spender, uint amount); From b3f88b358a6fd6974cfa2347fb6c2ec18f4bdeb4 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:18:01 +0800 Subject: [PATCH 018/156] fix: remove claimFees in IPair --- contracts/interfaces/IPair.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/interfaces/IPair.sol b/contracts/interfaces/IPair.sol index 0503a59e..988523d6 100644 --- a/contracts/interfaces/IPair.sol +++ b/contracts/interfaces/IPair.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.13; interface IPair { function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1); - function claimFees() external returns (uint, uint); function tokens() external returns (address, address); function transferFrom(address src, address dst, uint amount) external returns (bool); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; From 7e2d94e297e301176aeee7957cb2ce96e41ab6f5 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:26:23 +0800 Subject: [PATCH 019/156] fix: remove Pair fees from Pair.sol --- contracts/Pair.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index af7494d4..dab57c95 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -6,7 +6,6 @@ import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IPair.sol'; import 'contracts/interfaces/IPairCallee.sol'; import 'contracts/factories/PairFactory.sol'; -import 'contracts/PairFees.sol'; import 'contracts/interfaces/IBribe.sol'; @@ -34,7 +33,6 @@ contract Pair is IPair { address public immutable token0; address public immutable token1; - address public immutable fees; address immutable factory; address public externalBribe; address public voter; @@ -63,7 +61,6 @@ contract Pair is IPair { uint public reserve0CumulativeLast; uint public reserve1CumulativeLast; - event Fees(address indexed sender, uint amount0, uint amount1); event TankFees(address indexed token, uint amount0, address tank); event GaugeFees(address indexed token, uint amount0, address externalBribe); event Mint(address indexed sender, uint amount0, uint amount1); @@ -87,7 +84,6 @@ contract Pair is IPair { tank = PairFactory(msg.sender).tank(); (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); - fees = address(new PairFees(_token0, _token1)); if (_stable) { name = string(abi.encodePacked("StableV1 AMM - ", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); symbol = string(abi.encodePacked("sAMM-", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); From 26273159ffe739f68b08d4cff80c2eb6df697d36 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 15:27:14 +0800 Subject: [PATCH 020/156] fix: remove PairFees --- contracts/PairFees.sol | 33 ------------- test/BaseTest.sol | 1 - test/PairFees.t.sol | 108 ----------------------------------------- 3 files changed, 142 deletions(-) delete mode 100644 contracts/PairFees.sol delete mode 100644 test/PairFees.t.sol diff --git a/contracts/PairFees.sol b/contracts/PairFees.sol deleted file mode 100644 index 7a2ab438..00000000 --- a/contracts/PairFees.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -import 'contracts/interfaces/IERC20.sol'; - -// Pair Fees contract is used as a 1:1 pair relationship to split out fees, this ensures that the curve does not need to be modified for LP shares -contract PairFees { - - address internal immutable pair; // The pair it is bonded to - address internal immutable token0; // token0 of pair, saved localy and statically for gas optimization - address internal immutable token1; // Token1 of pair, saved localy and statically for gas optimization - - constructor(address _token0, address _token1) { - pair = msg.sender; - token0 = _token0; - token1 = _token1; - } - - function _safeTransfer(address token,address to,uint256 value) internal { - require(token.code.length > 0); - (bool success, bytes memory data) = - token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool)))); - } - - // Allow the pair to transfer fees to users - function claimFeesFor(address recipient, uint amount0, uint amount1) external { - require(msg.sender == pair); - if (amount0 > 0) _safeTransfer(token0, recipient, amount0); - if (amount1 > 0) _safeTransfer(token1, recipient, amount1); - } - -} diff --git a/test/BaseTest.sol b/test/BaseTest.sol index a5629e70..da7e97aa 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -14,7 +14,6 @@ import "contracts/ExternalBribe.sol"; import "contracts/Gauge.sol"; import "contracts/Minter.sol"; import "contracts/Pair.sol"; -import "contracts/PairFees.sol"; import "contracts/RewardsDistributor.sol"; import "contracts/Router.sol"; import "contracts/Velo.sol"; diff --git a/test/PairFees.t.sol b/test/PairFees.t.sol deleted file mode 100644 index 05ee3f78..00000000 --- a/test/PairFees.t.sol +++ /dev/null @@ -1,108 +0,0 @@ -// 1:1 with Hardhat test -pragma solidity 0.8.13; - -import "./BaseTest.sol"; - -contract PairFeesTest is BaseTest { - function setUp() public { - deployOwners(); - deployCoins(); - mintStables(); - deployPairFactoryAndRouter(); - factory.setFee(true, 2); // 2 bps = 0.02% - deployPairWithOwner(address(owner)); - mintPairFraxUsdcWithOwner(address(owner)); - } - - function testSwapAndClaimFees() public { - Router.route[] memory routes = new Router.route[](1); - routes[0] = Router.route(address(USDC), address(FRAX), true); - - assertEq( - router.getAmountsOut(USDC_1, routes)[1], - pair.getAmountOut(USDC_1, address(USDC)) - ); - - uint256[] memory assertedOutput = router.getAmountsOut(USDC_1, routes); - USDC.approve(address(router), USDC_1); - router.swapExactTokensForTokens( - USDC_1, - assertedOutput[1], - routes, - address(owner), - block.timestamp - ); - vm.warp(block.timestamp + 1801); - vm.roll(block.number + 1); - address fees = pair.fees(); - assertEq(USDC.balanceOf(fees), 200); // 0.01% -> 0.02% - uint256 b = USDC.balanceOf(address(owner)); - pair.claimFees(); - assertGt(USDC.balanceOf(address(owner)), b); - } - - function testNonFeeManagerCannotSetNextManager() public { - vm.expectRevert(abi.encodePacked("not fee manager")); - owner2.setFeeManager(address(factory), address(owner)); - } - - function testFeeManagerCanSetNextManager() public { - owner.setFeeManager(address(factory), address(owner2)); - assertEq(factory.pendingFeeManager(), address(owner2)); - } - - function testNonPendingManagerCannotAcceptManager() public { - vm.expectRevert(abi.encodePacked("not pending fee manager")); - owner2.acceptFeeManager(address(factory)); - } - - function testPendingManagerCanAcceptManager() public { - owner.setFeeManager(address(factory), address(owner2)); - owner2.acceptFeeManager(address(factory)); - assertEq(factory.feeManager(), address(owner2)); - } - - function testNonFeeManagerCannotChangeFees() public { - vm.expectRevert(abi.encodePacked("not fee manager")); - owner2.setFee(address(factory), true, 2); - } - - function testFeeManagerCannotSetFeeAboveMax() public { - vm.expectRevert(abi.encodePacked("fee too high")); - factory.setFee(true, 6); // 6 bps = 0.06% - } - - function testFeeManagerCannotSetZeroFee() public { - vm.expectRevert(abi.encodePacked("fee must be nonzero")); - factory.setFee(true, 0); - } - - function testFeeManagerCanChangeFeesAndClaim() public { - factory.setFee(true, 3); // 3 bps = 0.03% - - Router.route[] memory routes = new Router.route[](1); - routes[0] = Router.route(address(USDC), address(FRAX), true); - - assertEq( - router.getAmountsOut(USDC_1, routes)[1], - pair.getAmountOut(USDC_1, address(USDC)) - ); - - uint256[] memory assertedOutput = router.getAmountsOut(USDC_1, routes); - USDC.approve(address(router), USDC_1); - router.swapExactTokensForTokens( - USDC_1, - assertedOutput[1], - routes, - address(owner), - block.timestamp - ); - vm.warp(block.timestamp + 1801); - vm.roll(block.number + 1); - address fees = pair.fees(); - assertEq(USDC.balanceOf(fees), 300); - uint256 b = USDC.balanceOf(address(owner)); - pair.claimFees(); - assertGt(USDC.balanceOf(address(owner)), b); - } -} From 086457e2168825e669011018c193bf2bbab2dfa2 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 20:25:32 +0800 Subject: [PATCH 021/156] fix: remove claimFees in gauge --- contracts/Gauge.sol | 36 +------------------------------- contracts/Voter.sol | 10 +-------- contracts/interfaces/IGauge.sol | 1 - contracts/libraries/Math.sol | 34 ------------------------------ test/BaseTest.sol | 4 ++++ test/ExternalBribes.t.sol | 11 +++++++--- test/Imbalance.t.sol | 12 ++++++----- test/KillGauges.t.sol | 10 ++++++--- test/LPRewards.t.sol | 11 +++++++--- test/Minter.t.sol | 7 ++++++- test/MinterTeamEmissions.t.sol | 8 +++++-- test/Oracle.t.sol | 8 +++---- test/Pair.t.sol | 23 +++++++------------- test/VeloGovernor.t.sol | 17 ++++++++++----- test/VeloVoting.t.sol | 8 ++++++- test/WashTrade.t.sol | 12 ++++++----- test/WrappedExternalBribes.t.sol | 10 +++++---- test/utils/TestOwner.sol | 4 ---- 18 files changed, 90 insertions(+), 136 deletions(-) delete mode 100644 contracts/libraries/Math.sol diff --git a/contracts/Gauge.sol b/contracts/Gauge.sol index 611e35df..65325999 100644 --- a/contracts/Gauge.sol +++ b/contracts/Gauge.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import 'contracts/libraries/Math.sol'; +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IBribe.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IGauge.sol'; @@ -81,7 +81,6 @@ contract Gauge is IGauge { event Deposit(address indexed from, uint tokenId, uint amount); event Withdraw(address indexed from, uint tokenId, uint amount); event NotifyReward(address indexed from, address indexed reward, uint amount); - event ClaimFees(address indexed from, uint claimed0, uint claimed1); event ClaimRewards(address indexed from, address indexed reward, uint amount); constructor(address _stake, address _internal_bribe, address _external_bribe, address __ve, address _voter, bool _forPair, address[] memory _allowedRewardTokens) { @@ -109,38 +108,6 @@ contract Gauge is IGauge { _unlocked = 1; } - function claimFees() external lock returns (uint claimed0, uint claimed1) { - return _claimFees(); - } - - function _claimFees() internal returns (uint claimed0, uint claimed1) { - if (!isForPair) { - return (0, 0); - } - (claimed0, claimed1) = IPair(stake).claimFees(); - if (claimed0 > 0 || claimed1 > 0) { - uint _fees0 = fees0 + claimed0; - uint _fees1 = fees1 + claimed1; - (address _token0, address _token1) = IPair(stake).tokens(); - if (_fees0 > IBribe(internal_bribe).left(_token0) && _fees0 / DURATION > 0) { - fees0 = 0; - _safeApprove(_token0, internal_bribe, _fees0); - IBribe(internal_bribe).notifyRewardAmount(_token0, _fees0); - } else { - fees0 = _fees0; - } - if (_fees1 > IBribe(internal_bribe).left(_token1) && _fees1 / DURATION > 0) { - fees1 = 0; - _safeApprove(_token1, internal_bribe, _fees1); - IBribe(internal_bribe).notifyRewardAmount(_token1, _fees1); - } else { - fees1 = _fees1; - } - - emit ClaimFees(msg.sender, claimed0, claimed1); - } - } - /** * @notice Determine the prior balance for an account as of a block number * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. @@ -541,7 +508,6 @@ contract Gauge is IGauge { } if (rewardRate[token] == 0) _writeRewardPerTokenCheckpoint(token, 0, block.timestamp); (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, type(uint).max, true); - _claimFees(); if (block.timestamp >= periodFinish[token]) { _safeTransferFrom(token, msg.sender, address(this), amount); diff --git a/contracts/Voter.sol b/contracts/Voter.sol index dbc769e8..0e9ad193 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -44,7 +44,7 @@ contract Voter is IVoter { mapping(address => bool) public isWhitelisted; mapping(address => bool) public isAlive; - event GaugeCreated(address indexed gauge, address creator, address internal_bribe, address indexed external_bribe, address indexed pool); + event GaugeCreated(address indexed gauge, address creator, address internal_bribe, address indexed external_bribe, address wxbribe, address indexed pool); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted(address indexed voter, uint tokenId, uint256 weight); @@ -367,14 +367,6 @@ contract Voter is IVoter { } } - function distributeFees(address[] memory _gauges) external { - for (uint i = 0; i < _gauges.length; i++) { - if (IGauge(_gauges[i]).isForPair()){ - IGauge(_gauges[i]).claimFees(); - } - } - } - function distribute(address _gauge) public lock { IMinter(minter).update_period(); _updateFor(_gauge); // should set claimable to 0 if killed diff --git a/contracts/interfaces/IGauge.sol b/contracts/interfaces/IGauge.sol index f605df8c..4f51579b 100644 --- a/contracts/interfaces/IGauge.sol +++ b/contracts/interfaces/IGauge.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.13; interface IGauge { function notifyRewardAmount(address token, uint amount) external; function getReward(address account, address[] memory tokens) external; - function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function isForPair() external view returns (bool); } diff --git a/contracts/libraries/Math.sol b/contracts/libraries/Math.sol deleted file mode 100644 index bb315bee..00000000 --- a/contracts/libraries/Math.sol +++ /dev/null @@ -1,34 +0,0 @@ -pragma solidity 0.8.13; - -library Math { - function max(uint a, uint b) internal pure returns (uint) { - return a >= b ? a : b; - } - function min(uint a, uint b) internal pure returns (uint) { - return a < b ? a : b; - } - function sqrt(uint y) internal pure returns (uint z) { - if (y > 3) { - z = y; - uint x = y / 2 + 1; - while (x < z) { - z = x; - x = (y / x + x) / 2; - } - } else if (y != 0) { - z = 1; - } - } - function cbrt(uint256 n) internal pure returns (uint256) { unchecked { - uint256 x = 0; - for (uint256 y = 1 << 255; y > 0; y >>= 3) { - x <<= 1; - uint256 z = 3 * x * (x + 1) + 1; - if (n / y >= z) { - n -= y * z; - x += 1; - } - } - return x; - }} -} diff --git a/test/BaseTest.sol b/test/BaseTest.sol index da7e97aa..edd1a61b 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -6,6 +6,7 @@ import "solmate/test/utils/mocks/MockERC20.sol"; import "contracts/factories/BribeFactory.sol"; import "contracts/factories/GaugeFactory.sol"; import "contracts/factories/PairFactory.sol"; +import "contracts/factories/WrappedExternalBribeFactory.sol"; import "contracts/redeem/MerkleClaim.sol"; import "contracts/redeem/RedemptionReceiver.sol"; import "contracts/redeem/RedemptionSender.sol"; @@ -121,6 +122,9 @@ abstract contract BaseTest is Test, TestOwner { assertEq(factory.allPairsLength(), 0); factory.setFee(true, 1); // set fee back to 0.01% for old tests factory.setFee(false, 1); + factory.setTeam(address(msg.sender)); // set team + factory.setTank(address(msg.sender)); // set tank + router = new Router(address(factory), address(WETH)); assertEq(router.factory(), address(factory)); lib = new VelodromeLibrary(address(router)); diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index c474fa87..134949b3 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -6,12 +6,14 @@ contract ExternalBribesTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; Gauge gauge; InternalBribe bribe; ExternalBribe xbribe; + PairFactory pairFactory; function setUp() public { vm.warp(block.timestamp + 1 weeks); // put some initial time in @@ -28,16 +30,19 @@ contract ExternalBribesTest is BaseTest { VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); deployPairFactoryAndRouter(); - deployPairWithOwner(address(owner)); // deployVoter() gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); escrow.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); + // setVoter on pairFactory. factory defined in BaseTest and we know for sure that it is deployed because of deployPairFactoryAndRouter() + factory.setVoter(address(voter)); + deployPairWithOwner(address(owner)); - // deployMinter() distributor = new RewardsDistributor(address(escrow)); minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); diff --git a/test/Imbalance.t.sol b/test/Imbalance.t.sol index 2c6b72cc..71e05a49 100644 --- a/test/Imbalance.t.sol +++ b/test/Imbalance.t.sol @@ -7,6 +7,7 @@ contract ImbalanceTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; Gauge gauge; InternalBribe bribe; @@ -47,6 +48,7 @@ contract ImbalanceTest is BaseTest { function confirmTokensForFraxUsdc() public { votingEscrowMerge(); deployPairFactoryAndRouter(); + deployVoter(); deployPairWithOwner(address(owner)); (address token0, address token1) = router.sortTokens(address(USDC), address(FRAX)); @@ -78,11 +80,12 @@ contract ImbalanceTest is BaseTest { } function deployVoter() public { - routerAddLiquidity(); - gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); address[] memory tokens = new address[](4); tokens[0] = address(USDC); tokens[1] = address(FRAX); @@ -94,8 +97,7 @@ contract ImbalanceTest is BaseTest { } function deployPairFactoryGauge() public { - deployVoter(); - + routerAddLiquidity(); VELO.approve(address(gaugeFactory), 5 * TOKEN_100K); voter.createGauge(address(pair3)); assertFalse(voter.gauges(address(pair3)) == address(0)); diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index 9e04883d..4ed56891 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -6,6 +6,7 @@ contract KillGaugesTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -34,19 +35,22 @@ contract KillGaugesTest is BaseTest { deployPairFactoryAndRouter(); - deployPairWithOwner(address(owner)); - gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); + wxbribeFactory = new WrappedExternalBribeFactory(); voter = new Voter( address(escrow), address(factory), address(gaugeFactory), - address(bribeFactory) + address(bribeFactory), + address(wxbribeFactory) ); escrow.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + deployPairWithOwner(address(owner)); distributor = new RewardsDistributor(address(escrow)); minter = new Minter(address(voter), address(escrow), address(distributor)); diff --git a/test/LPRewards.t.sol b/test/LPRewards.t.sol index 9c52548f..8c9140ef 100644 --- a/test/LPRewards.t.sol +++ b/test/LPRewards.t.sol @@ -6,6 +6,7 @@ contract LPRewardsTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; Gauge gauge; @@ -26,11 +27,15 @@ contract LPRewardsTest is BaseTest { escrow.create_lock(TOKEN_1M, 4 * 365 * 86400); deployPairFactoryAndRouter(); - deployPairWithOwner(address(owner)); - deployPairWithOwner(address(owner2)); + gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + deployPairWithOwner(address(owner)); + deployPairWithOwner(address(owner2)); address[] memory tokens = new address[](4); tokens[0] = address(USDC); tokens[1] = address(FRAX); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 2ffea8de..f36d4d53 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -7,6 +7,7 @@ contract MinterTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -27,7 +28,11 @@ contract MinterTest is BaseTest { router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); + + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); address[] memory tokens = new address[](2); tokens[0] = address(FRAX); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index 3ecb6ae7..921ddcff 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -7,6 +7,7 @@ contract MinterTeamEmissions is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -29,13 +30,16 @@ contract MinterTeamEmissions is BaseTest { router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); + wxbribeFactory = new WrappedExternalBribeFactory(); voter = new Voter( address(escrow), address(factory), address(gaugeFactory), - address(bribeFactory) + address(bribeFactory), + address(wxbribeFactory) ); - + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); address[] memory tokens = new address[](2); tokens[0] = address(FRAX); tokens[1] = address(VELO); diff --git a/test/Oracle.t.sol b/test/Oracle.t.sol index 12b90099..f150181a 100644 --- a/test/Oracle.t.sol +++ b/test/Oracle.t.sol @@ -72,11 +72,9 @@ contract OracleTest is BaseTest { vm.roll(block.number + 1); USDC.approve(address(router), USDC_1); router.swapExactTokensForTokens(USDC_1, 0, routes, address(owner), block.timestamp); - address fees = pair.fees(); - assertEq(USDC.balanceOf(fees), 400); - uint256 b = USDC.balanceOf(address(owner)); - pair.claimFees(); - assertGt(USDC.balanceOf(address(owner)), b); + address tank = pair.tank(); + assertFalse(tank == address(0)); + assertEq(USDC.balanceOf(tank), 400); // tank should have 400 USDC } function testOracle() public { diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 1064e6d8..23529a5b 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -7,6 +7,7 @@ contract PairTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -123,6 +124,7 @@ contract PairTest is BaseTest { function confirmTokensForFraxUsdc() public { confirmFraxDeployment(); deployPairFactoryAndRouter(); + routerAddLiquidity(); deployPairWithOwner(address(owner)); deployPairWithOwner(address(owner2)); @@ -203,11 +205,6 @@ contract PairTest is BaseTest { router.swapExactTokensForTokens(USDC_1, assertedOutput[1], routes, address(owner), block.timestamp); vm.warp(block.timestamp + 1801); vm.roll(block.number + 1); - address fees = pair.fees(); - assertEq(USDC.balanceOf(fees), 100); - uint256 b = USDC.balanceOf(address(owner)); - pair.claimFees(); - assertGt(USDC.balanceOf(address(owner)), b); } function routerPair1GetAmountsOutAndSwapExactTokensForTokensOwner2() public { @@ -221,11 +218,6 @@ contract PairTest is BaseTest { uint256[] memory expectedOutput = router.getAmountsOut(USDC_1, routes); owner2.approve(address(USDC), address(router), USDC_1); owner2.swapExactTokensForTokens(payable(address(router)), USDC_1, expectedOutput[1], routes, address(owner2), block.timestamp); - address fees = pair.fees(); - assertEq(USDC.balanceOf(fees), 101); - uint256 b = USDC.balanceOf(address(owner)); - owner2.claimFees(address(pair)); - assertEq(USDC.balanceOf(address(owner)), b); } function routerPair2GetAmountsOutAndSwapExactTokensForTokens() public { @@ -255,19 +247,19 @@ contract PairTest is BaseTest { } function deployVoter() public { - routerAddLiquidity(); - gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); escrow.setVoter(address(voter)); - + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); assertEq(voter.length(), 0); } function deployMinter() public { - deployVoter(); + routerAddLiquidity(); distributor = new RewardsDistributor(address(escrow)); @@ -601,7 +593,6 @@ contract PairTest is BaseTest { address[] memory gauges = new address[](1); gauges[0] = address(gauge); - voter.distributeFees(gauges); } function minterMint() public { diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol index 458b1715..0358b0fb 100644 --- a/test/VeloGovernor.t.sol +++ b/test/VeloGovernor.t.sol @@ -7,6 +7,7 @@ contract VeloGovernorTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -40,15 +41,18 @@ contract VeloGovernorTest is BaseTest { deployPairFactoryAndRouter(); - USDC.approve(address(router), USDC_100K); - FRAX.approve(address(router), TOKEN_100K); - router.addLiquidity(address(FRAX), address(USDC), true, TOKEN_100K, USDC_100K, TOKEN_100K, USDC_100K, address(owner), block.timestamp); - gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); escrow.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + + USDC.approve(address(router), USDC_100K); + FRAX.approve(address(router), TOKEN_100K); + router.addLiquidity(address(FRAX), address(USDC), true, TOKEN_100K, USDC_100K, TOKEN_100K, USDC_100K, address(owner), block.timestamp); distributor = new RewardsDistributor(address(escrow)); @@ -56,6 +60,9 @@ contract VeloGovernorTest is BaseTest { distributor.setDepositor(address(minter)); VELO.setMinter(address(minter)); + address address1 = factory.getPair(address(FRAX), address(USDC), true); + pair = Pair(address1); + VELO.approve(address(gaugeFactory), 15 * TOKEN_100K); voter.createGauge(address(pair)); address gaugeAddress = voter.gauges(address(pair)); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index aeab7f03..443d5fdf 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -7,6 +7,7 @@ contract VeloVotingTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -29,13 +30,18 @@ contract VeloVotingTest is BaseTest { router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); + wxbribeFactory = new WrappedExternalBribeFactory(); voter = new Voter( address(escrow), address(factory), address(gaugeFactory), - address(bribeFactory) + address(bribeFactory), + address(wxbribeFactory) ); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + address[] memory tokens = new address[](2); tokens[0] = address(FRAX); tokens[1] = address(VELO); diff --git a/test/WashTrade.t.sol b/test/WashTrade.t.sol index 1e7efebc..b00ac36b 100644 --- a/test/WashTrade.t.sol +++ b/test/WashTrade.t.sol @@ -7,6 +7,7 @@ contract WashTradeTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; Gauge gauge3; InternalBribe bribe3; @@ -82,11 +83,13 @@ contract WashTradeTest is BaseTest { } function deployVoter() public { - routerAddLiquidity(); - gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + address[] memory tokens = new address[](4); tokens[0] = address(USDC); tokens[1] = address(FRAX); @@ -98,7 +101,7 @@ contract WashTradeTest is BaseTest { } function deployPairFactoryGauge() public { - deployVoter(); + routerAddLiquidity(); VELO.approve(address(gaugeFactory), 5 * TOKEN_100K); voter.createGauge(address(pair3)); @@ -194,7 +197,6 @@ contract WashTradeTest is BaseTest { address[] memory gauges = new address[](1); gauges[0] = address(gauge3); - voter.distributeFees(gauges); } function testBribeClaimRewards() public { diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index 734df433..1e15d242 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -32,15 +32,17 @@ contract WrappedExternalBribesTest is BaseTest { VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); deployPairFactoryAndRouter(); - deployPairWithOwner(address(owner)); // deployVoter() gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory)); - wxbribeFactory = new WrappedExternalBribeFactory(address(voter)); + wxbribeFactory = new WrappedExternalBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); escrow.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + deployPairWithOwner(address(owner)); // deployMinter() distributor = new RewardsDistributor(address(escrow)); @@ -63,7 +65,7 @@ contract WrappedExternalBribesTest is BaseTest { gauge = Gauge(voter.createGauge(address(pair))); bribe = InternalBribe(gauge.internal_bribe()); xbribe = ExternalBribe(gauge.external_bribe()); - wxbribe = WrappedExternalBribe(wxbribeFactory.createBribe(address(xbribe))); + wxbribe = WrappedExternalBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); // ve VELO.approve(address(escrow), TOKEN_1); diff --git a/test/utils/TestOwner.sol b/test/utils/TestOwner.sol index bd3510a7..b283fafc 100644 --- a/test/utils/TestOwner.sol +++ b/test/utils/TestOwner.sol @@ -36,10 +36,6 @@ contract TestOwner { Pair //////////////////////////////////////////////////////////////*/ - function claimFees(address _pair) public { - Pair(_pair).claimFees(); - } - function mint(address _pair, address _to) public { Pair(_pair).mint(_to); } From 62d571afde2a309770a9bc438c9e67bef18aa983 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 20:32:31 +0800 Subject: [PATCH 022/156] fix: setHasGauge in killGauge and reviveGauge function in Voter.sol --- contracts/Voter.sol | 4 ++++ contracts/interfaces/IGauge.sol | 1 + 2 files changed, 5 insertions(+) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 0e9ad193..80f24193 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -257,6 +257,8 @@ contract Voter is IVoter { require(isAlive[_gauge], "gauge already dead"); isAlive[_gauge] = false; claimable[_gauge] = 0; + address _pair = IGauge(_gauge).stake(); // TODO: add test cases + IPair(_pair).setHasGauge(bool false); emit GaugeKilled(_gauge); } @@ -264,6 +266,8 @@ contract Voter is IVoter { require(msg.sender == emergencyCouncil, "not emergency council"); require(!isAlive[_gauge], "gauge already alive"); isAlive[_gauge] = true; + address _pair = IGauge(_gauge).stake(); // TODO: add test cases + IPair(_pair).setHasGauge(bool true); emit GaugeRevived(_gauge); } diff --git a/contracts/interfaces/IGauge.sol b/contracts/interfaces/IGauge.sol index 4f51579b..d3018c33 100644 --- a/contracts/interfaces/IGauge.sol +++ b/contracts/interfaces/IGauge.sol @@ -5,4 +5,5 @@ interface IGauge { function getReward(address account, address[] memory tokens) external; function left(address token) external view returns (uint); function isForPair() external view returns (bool); + function stake() external view returns (address); } From 7a7a4882e1544726aa9393e96730190f497ecae6 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:03:36 +0800 Subject: [PATCH 023/156] fix: can set fee to zero --- contracts/factories/PairFactory.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 6e157449..e6fe77b6 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -88,7 +88,6 @@ contract PairFactory is IPairFactory { function setFee(bool _stable, uint256 _fee) external { require(msg.sender == feeManager, 'not fee manager'); require(_fee <= MAX_FEE, 'fee too high'); - require(_fee != 0, 'fee must be nonzero'); if (_stable) { stableFee = _fee; } else { From c3202ca3cf20723b3f8dc1d2005fac3a434a805e Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:07:13 +0800 Subject: [PATCH 024/156] fix: add back checking for setFee in PairFactory --- contracts/factories/PairFactory.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index e6fe77b6..6e157449 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -88,6 +88,7 @@ contract PairFactory is IPairFactory { function setFee(bool _stable, uint256 _fee) external { require(msg.sender == feeManager, 'not fee manager'); require(_fee <= MAX_FEE, 'fee too high'); + require(_fee != 0, 'fee must be nonzero'); if (_stable) { stableFee = _fee; } else { From 46339504b75436c20e78863fe4d77ff7ce0f764c Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:11:39 +0800 Subject: [PATCH 025/156] chore: remove comments --- contracts/Voter.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 80f24193..0b339017 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -246,8 +246,8 @@ contract Voter is IVoter { isAlive[_gauge] = true; _updateFor(_gauge); pools.push(_pool); - IPair(_pool).setHasGauge(true); // may need to switch to IPair? - IPair(_pool).setExternalBribe(_wxbribe); // Changed this to wrapped external bribe from + IPair(_pool).setHasGauge(true); + IPair(_pool).setExternalBribe(_wxbribe); emit GaugeCreated(_gauge, msg.sender, _internal_bribe, _external_bribe, _wxbribe, _pool); return _gauge; } From 0635e3fca159c037f46458f5fe763ff95313c995 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:24:07 +0800 Subject: [PATCH 026/156] fix: fix code error --- contracts/Voter.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 0b339017..9ff7ab20 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -258,7 +258,7 @@ contract Voter is IVoter { isAlive[_gauge] = false; claimable[_gauge] = 0; address _pair = IGauge(_gauge).stake(); // TODO: add test cases - IPair(_pair).setHasGauge(bool false); + IPair(_pair).setHasGauge(false); emit GaugeKilled(_gauge); } @@ -267,7 +267,7 @@ contract Voter is IVoter { require(!isAlive[_gauge], "gauge already alive"); isAlive[_gauge] = true; address _pair = IGauge(_gauge).stake(); // TODO: add test cases - IPair(_pair).setHasGauge(bool true); + IPair(_pair).setHasGauge(true); emit GaugeRevived(_gauge); } From eea30e94e18456783c9c58b655dd18e59bbfc3ac Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:24:33 +0800 Subject: [PATCH 027/156] feat: add event VoterSet in WrappedExternalBribeFactory --- contracts/factories/WrappedExternalBribeFactory.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/factories/WrappedExternalBribeFactory.sol b/contracts/factories/WrappedExternalBribeFactory.sol index 51374e04..1e4aad81 100644 --- a/contracts/factories/WrappedExternalBribeFactory.sol +++ b/contracts/factories/WrappedExternalBribeFactory.sol @@ -8,6 +8,8 @@ contract WrappedExternalBribeFactory { mapping(address => address) public oldBribeToNew; address public last_bribe; + event VoterSet(address indexed setter, address indexed voter); + function createBribe(address existing_bribe) external returns (address) { require( oldBribeToNew[existing_bribe] == address(0), @@ -21,5 +23,6 @@ contract WrappedExternalBribeFactory { function setVoter(address _voter) external { require(voter == address(0), "Already initialized"); voter = _voter; + emit VoterSet(msg.sender, _voter); } } From 421035d4f3155bdc99586fbb9d4c340f300da109 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:37:59 +0800 Subject: [PATCH 028/156] feat: add events in PairFactory --- contracts/factories/PairFactory.sol | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 6e157449..5b77d9a6 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -29,6 +29,16 @@ contract PairFactory is IPairFactory { bool internal _temp; event PairCreated(address indexed token0, address indexed token1, bool stable, address pair, uint); + event TeamSet(address indexed setter, address indexed team); + event VoterSet(address indexed setter, address indexed voter); + event TankSet(address indexed setter, address indexed tank); + event PauserSet(address indexed setter, address indexed pauser); + event PauserAccepted(address indexed previous, address indexed current); + event Paused(address indexed pauser, bool paused); + event FeeManagerSet(address indexed setter, address indexed feeManager); + event FeeManagerAccepted(address indexed previous, address indexed current); + + event FeeSet(address indexed setter, bool stable, uint256 fee); constructor() { pauser = msg.sender; @@ -43,17 +53,20 @@ contract PairFactory is IPairFactory { require(team == address(0), 'The team has already been set.'); require(msg.sender == deployer, 'Not authorised to set team.'); // might need to set this to deployer?? or just make it team = _team; + emit TeamSet(msg.sender, _team); } function setVoter(address _voter) external { require(voter == address(0), 'The voter has already been set.'); require(msg.sender == deployer, 'Not authorised to set voter.'); // have to make sure that this can be set to the voter addres during init script voter = _voter; + emit VoterSet(msg.sender, _voter); } function setTank(address _tank) external { require(msg.sender == deployer || msg.sender == team, 'Not authorised to set tank.'); // this should be updateable to team but adding deployer so that init script can run.. tank = _tank; + emit TankSet(msg.sender, _tank); } function allPairsLength() external view returns (uint) { @@ -63,26 +76,33 @@ contract PairFactory is IPairFactory { function setPauser(address _pauser) external { require(msg.sender == pauser); pendingPauser = _pauser; + emit PauserSet(msg.sender, _pauser); } function acceptPauser() external { require(msg.sender == pendingPauser); + address prevPauser = pauser; pauser = pendingPauser; + emit PauserAccepted(prevPauser, msg.sender); } function setPause(bool _state) external { require(msg.sender == pauser); isPaused = _state; + emit Paused(msg.sender, _state); } function setFeeManager(address _feeManager) external { require(msg.sender == feeManager, 'not fee manager'); pendingFeeManager = _feeManager; + emit FeeManagerSet(msg.sender, _feeManager); } function acceptFeeManager() external { require(msg.sender == pendingFeeManager, 'not pending fee manager'); + address prevFeeManager = feeManager; feeManager = pendingFeeManager; + emit FeeManagerAccepted(prevFeeManager, msg.sender); } function setFee(bool _stable, uint256 _fee) external { @@ -94,6 +114,7 @@ contract PairFactory is IPairFactory { } else { volatileFee = _fee; } + emit FeeSet(msg.sender, _stable, _fee); } function getFee(bool _stable) public view returns(uint256) { From af5fd001e2a90f65c35c7b644d3e96aeaa16130e Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 3 Mar 2023 22:40:40 +0800 Subject: [PATCH 029/156] feat: add events in Pair.sol --- contracts/Pair.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index dab57c95..78901497 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -78,6 +78,9 @@ contract Pair is IPair { event Transfer(address indexed from, address indexed to, uint amount); event Approval(address indexed owner, address indexed spender, uint amount); + event ExternalBribeSet(address indexed setter, address indexed externalBribe); + event HasGaugeSet(address indexed setter, bool value); + constructor() { factory = msg.sender; voter = PairFactory(msg.sender).voter(); @@ -119,11 +122,13 @@ contract Pair is IPair { externalBribe = _externalBribe; _safeApprove(token0, externalBribe, type(uint).max); _safeApprove(token1, externalBribe, type(uint).max); + emit ExternalBribeSet(msg.sender, _externalBribe); } function setHasGauge(bool value) external { require(msg.sender == voter, 'Only voter can set has gauge'); hasGauge = value; + emit HasGaugeSet(msg.sender, value); } function observationLength() external view returns (uint) { From 4e8343e803ed1baa1f0e2d46ce3ced117e50e463 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 21:17:46 +0000 Subject: [PATCH 030/156] fix: Forge config deprecated --- foundry.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foundry.toml b/foundry.toml index bbcd04e0..d6f4c599 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,3 +1,3 @@ -[default] +[profile.default] src = 'contracts' out = 'artifacts' From b6b096c4fc3fa30a858d56a365eb217f61509834 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:05:58 +0000 Subject: [PATCH 031/156] build: Add yarn.lock --- yarn.lock | 8527 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 8527 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..d8773935 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8527 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@ensdomains/ens@^0.4.4": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/resolver@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== + +"@ethereum-waffle/chai@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.4.tgz#16c4cc877df31b035d6d92486dfdf983df9138ff" + integrity sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g== + dependencies: + "@ethereum-waffle/provider" "^3.4.4" + ethers "^5.5.2" + +"@ethereum-waffle/compiler@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz#d568ee0f6029e68b5c645506079fbf67d0dfcf19" + integrity sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ== + dependencies: + "@resolver-engine/imports" "^0.3.3" + "@resolver-engine/imports-fs" "^0.3.3" + "@typechain/ethers-v5" "^2.0.0" + "@types/mkdirp" "^0.5.2" + "@types/node-fetch" "^2.5.5" + ethers "^5.0.1" + mkdirp "^0.5.1" + node-fetch "^2.6.1" + solc "^0.6.3" + ts-generator "^0.1.1" + typechain "^3.0.0" + +"@ethereum-waffle/ens@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.4.4.tgz#db97ea2c9decbb70b9205d53de2ccbd6f3182ba1" + integrity sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg== + dependencies: + "@ensdomains/ens" "^0.4.4" + "@ensdomains/resolver" "^0.2.4" + ethers "^5.5.2" + +"@ethereum-waffle/mock-contract@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz#fc6ffa18813546f4950a69f5892d4dd54b2c685a" + integrity sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA== + dependencies: + "@ethersproject/abi" "^5.5.0" + ethers "^5.5.2" + +"@ethereum-waffle/provider@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.4.4.tgz#398fc1f7eb91cc2df7d011272eacba8af0c7fffb" + integrity sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g== + dependencies: + "@ethereum-waffle/ens" "^3.4.4" + ethers "^5.5.2" + ganache-core "^2.13.2" + patch-package "^6.2.2" + postinstall-postinstall "^2.1.0" + +"@ethersproject/abi@5.0.0-beta.153": + version "5.0.0-beta.153" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" + integrity sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg== + dependencies: + "@ethersproject/address" ">=5.0.0-beta.128" + "@ethersproject/bignumber" ">=5.0.0-beta.130" + "@ethersproject/bytes" ">=5.0.0-beta.129" + "@ethersproject/constants" ">=5.0.0-beta.128" + "@ethersproject/hash" ">=5.0.0-beta.128" + "@ethersproject/keccak256" ">=5.0.0-beta.127" + "@ethersproject/logger" ">=5.0.0-beta.129" + "@ethersproject/properties" ">=5.0.0-beta.131" + "@ethersproject/strings" ">=5.0.0-beta.130" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/address@5.7.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + +"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + +"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" + integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/constants@5.7.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + +"@ethersproject/contracts@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" + integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + +"@ethersproject/hash@5.7.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" + integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" + integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@5.7.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + +"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" + integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + +"@ethersproject/properties@5.7.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/providers@5.7.2": + version "5.7.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + bech32 "1.1.4" + ws "7.4.6" + +"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" + integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" + integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + hash.js "1.1.7" + +"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/solidity@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/strings@5.7.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/units@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/wallet@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/hdnode" "^5.7.0" + "@ethersproject/json-wallets" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/wordlists" "^5.7.0" + +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" + integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@metamask/eth-sig-util@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" + integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== + dependencies: + ethereumjs-abi "^0.6.8" + ethereumjs-util "^6.2.1" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@morgan-stanley/ts-mocking-bird@^0.6.2": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz#2e4b60d42957bab3b50b67dbf14c3da2f62a39f7" + integrity sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA== + dependencies: + lodash "^4.17.16" + uuid "^7.0.3" + +"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" + integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== + +"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" + integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== + +"@nomicfoundation/ethereumjs-block@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz#fdd5c045e7baa5169abeed0e1202bf94e4481c49" + integrity sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-blockchain@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz#1a8c243a46d4d3691631f139bfb3a4a157187b0c" + integrity sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw== + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-ethash" "^2.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + +"@nomicfoundation/ethereumjs-common@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz#f6bcc7753994555e49ab3aa517fc8bcf89c280b9" + integrity sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA== + dependencies: + "@nomicfoundation/ethereumjs-util" "^8.0.0" + crc-32 "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz#11539c32fe0990e1122ff987d1b84cfa34774e81" + integrity sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew== + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-evm@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz#99cd173c03b59107c156a69c5e215409098a370b" + integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz#d9a9c5f0f10310c8849b6525101de455a53e771d" + integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw== + +"@nomicfoundation/ethereumjs-statemanager@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz#14a9d4e1c828230368f7ab520c144c34d8721e4b" + integrity sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + +"@nomicfoundation/ethereumjs-trie@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz#dcfbe3be53a94bc061c9767a396c16702bc2f5b7" + integrity sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz#59dc7452b0862b30342966f7052ab9a1f7802f52" + integrity sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz#deb2b15d2c308a731e82977aefc4e61ca0ece6c5" + integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-vm@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz#2bb50d332bf41790b01a3767ffec3987585d1de6" + integrity sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w== + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-blockchain" "^6.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-evm" "^1.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-statemanager" "^1.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" + integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== + +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" + integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== + +"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" + integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" + integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" + integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" + integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" + integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== + +"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" + integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== + +"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" + integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" + integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== + +"@nomicfoundation/solidity-analyzer@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" + integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" + +"@nomiclabs/hardhat-ethers@^2.0.6": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.2.tgz#812d48929c3bf8fe840ec29eab4b613693467679" + integrity sha512-NLDlDFL2us07C0jB/9wzvR0kuLivChJWCXTKcj3yqjZqMoYp7g7wwS157F70VHx/+9gHIBGzak5pKDwG8gEefA== + +"@nomiclabs/hardhat-etherscan@^3.0.4": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" + integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + fs-extra "^7.0.1" + lodash "^4.17.11" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" + +"@nomiclabs/hardhat-waffle@^2.0.3": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.5.tgz#97c217f1db795395c04404291937edb528f3f218" + integrity sha512-U1RH9OQ1mWYQfb+moX5aTgGjpVVlOcpiFI47wwnaGG4kLhcTy90cNiapoqZenxcRAITVbr0/+QSduINL5EsUIQ== + +"@resolver-engine/core@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" + integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== + dependencies: + debug "^3.1.0" + is-url "^1.2.4" + request "^2.85.0" + +"@resolver-engine/fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" + integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports-fs@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" + integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== + dependencies: + "@resolver-engine/fs" "^0.3.3" + "@resolver-engine/imports" "^0.3.3" + debug "^3.1.0" + +"@resolver-engine/imports@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" + integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== + dependencies: + "@resolver-engine/core" "^0.3.3" + debug "^3.1.0" + hosted-git-info "^2.6.0" + path-browserify "^1.0.0" + url "^0.11.0" + +"@scure/base@~1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + +"@scure/bip32@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" + integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== + dependencies: + "@noble/hashes" "~1.2.0" + "@noble/secp256k1" "~1.7.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" + integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== + dependencies: + "@noble/hashes" "~1.2.0" + "@scure/base" "~1.1.0" + +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sentry/node@^5.18.1": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== + dependencies: + "@sentry/core" "5.30.0" + "@sentry/hub" "5.30.0" + "@sentry/tracing" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/tracing@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== + +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== + dependencies: + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@solidity-parser/parser@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.0.tgz#1fb418c816ca1fc3a1e94b08bcfe623ec4e1add4" + integrity sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q== + dependencies: + antlr4ts "^0.5.0-alpha.4" + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + +"@typechain/ethers-v5@^10.0.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz#68f5963efb5214cb2d881477228e4b5b315473e1" + integrity sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + +"@typechain/ethers-v5@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz#cd3ca1590240d587ca301f4c029b67bfccd08810" + integrity sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw== + dependencies: + ethers "^5.0.2" + +"@typechain/hardhat@^6.0.0": + version "6.1.5" + resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.5.tgz#caad58a1d3e9cd88061a584eb4f4fa763d5dcad1" + integrity sha512-lg7LW4qDZpxFMknp3Xool61Fg6Lays8F8TXdFGBG+MxyYcYU5795P1U2XdStuzGq9S2Dzdgh+1jGww9wvZ6r4Q== + dependencies: + fs-extra "^9.1.0" + +"@types/async-eventemitter@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" + integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg== + +"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/bn.js@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" + integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== + dependencies: + "@types/node" "*" + +"@types/cacheable-request@^6.0.1": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + +"@types/chai@^4.3.0": + version "4.3.4" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" + integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== + +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/lru-cache@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" + integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== + +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/mocha@^9.1.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + +"@types/node-fetch@^2.5.5": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" + integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*": + version "18.14.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.6.tgz#ae1973dd2b1eeb1825695bb11ebfb746d27e3e93" + integrity sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA== + +"@types/node@^12.12.6": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + +"@types/node@^17.0.35": + version "17.0.45" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" + integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== + +"@types/pbkdf2@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" + integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== + dependencies: + "@types/node" "*" + +"@types/prettier@^2.1.1": + version "2.7.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" + integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + +"@types/resolve@^0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== + dependencies: + "@types/node" "*" + +"@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" + integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== + dependencies: + "@types/node" "*" + +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" + integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + +abstract-leveldown@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" + integrity sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: + version "2.7.2" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" + integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" + integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@~2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" + integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== + dependencies: + xtend "~4.0.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +adm-zip@^0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== + +aes-js@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-colors@^4.1.0, ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +antlr4ts@^0.5.0-alpha.4: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-back@^1.0.3, array-back@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" + integrity sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw== + dependencies: + typical "^2.6.0" + +array-back@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" + integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== + dependencies: + typical "^2.6.1" + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1, array-back@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +array.prototype.reduce@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" + integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== + dependencies: + async "^2.4.0" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + dependencies: + lodash "^4.17.11" + +async@^1.4.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== + +async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g== + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.14, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q== + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ== + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ== + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q== + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg== + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw== + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ== + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw== + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ== + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ== + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw== + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw== + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag== + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw== + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA== + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg== + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw== + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA== + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ== + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ== + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ== + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ== + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg== + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A== + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg== + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA== + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g== + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babelify@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" + integrity sha512-vID8Fz6pPN5pJMdlUnNFSfrlcx5MUule4k9aKs/zbZPyXxMTcRrB0M4Tarw22L8afr8eYSWxDPYCob3TdrqtlA== + dependencies: + babel-core "^6.0.14" + object-assign "^4.0.0" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backoff@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" + integrity sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA== + dependencies: + precond "0.2" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2, base-x@^3.0.8: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +bech32@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bigint-crypto-utils@^3.0.23: + version "3.1.8" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" + integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== + dependencies: + bigint-mod-arith "^3.1.0" + +bigint-mod-arith@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" + integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== + +bignumber.js@^9.0.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bip39@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" + integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== + dependencies: + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + unorm "^1.3.3" + +blakejs@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== + +bluebird@^3.5.0, bluebird@^3.5.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@^1.16.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-level@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" + integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.1" + module-error "^1.0.2" + run-parallel-limit "^1.1.0" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer-xor@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" + integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== + dependencies: + safe-buffer "^5.1.1" + +buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +bytewise-core@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" + integrity sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA== + dependencies: + typewise-core "^1.2" + +bytewise@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" + integrity sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ== + dependencies: + bytewise-core "^1.2.2" + typewise "^1.0.3" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + +cachedown@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" + integrity sha512-t+yVk82vQWCJF3PsWHMld+jhhjkkWjcAzz8NbFx1iULOXWl8Tm/FdM4smZNVw3MRr0X+lVTx9PKzvEn4Ng19RQ== + dependencies: + abstract-leveldown "^2.4.1" + lru-cache "^3.2.0" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30000844: + version "1.0.30001460" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001460.tgz#31d2e26f0a2309860ed3eff154e03890d9d851a7" + integrity sha512-Bud7abqjvEjipUkpLs4D7gR0l8hBYBHoa+tGtKJHvT2AYzLp1z7EmVkUT4ERpVUfca8S2HGIVs883D8pUH1ZzQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +catering@^2.1.0, catering@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== + +cbor@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" + integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== + dependencies: + nofilter "^3.1.0" + +chai@^4.3.6: + version "4.3.7" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" + integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^4.1.2" + get-func-name "^2.0.0" + loupe "^2.3.1" + pathval "^1.1.1" + type-detect "^4.0.5" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== + +checkpoint-store@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" + integrity sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg== + dependencies: + functional-red-black-tree "^1.0.1" + +chokidar@3.5.3, chokidar@^3.4.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +classic-level@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" + integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "~2.0.0" + node-gyp-build "^4.3.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +clone@2.1.2, clone@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + +command-line-args@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" + integrity sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA== + dependencies: + array-back "^2.0.0" + find-replace "^1.0.3" + typical "^2.6.1" + +command-line-args@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== + dependencies: + array-back "^4.0.2" + chalk "^2.4.2" + table-layout "^1.0.2" + typical "^5.2.0" + +commander@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.5.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-hash@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== + dependencies: + cids "^0.7.1" + multicodec "^0.5.5" + multihashes "^0.4.15" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^1.5.1: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cookiejar@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +core-js-pure@^3.0.1: + version "3.29.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.29.0.tgz#0e1ac889214398641ea4bb1c6cf25ff0959ec1d2" + integrity sha512-v94gUjN5UTe1n0yN/opTihJ8QBWD2O8i19RfTZR7foONPWArnjB96QA/wk5ozu1mm6ja3udQCzOzwQXTxi3xOQ== + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +crc-32@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-fetch@^2.1.0, cross-fetch@^2.1.1: + version "2.2.6" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.6.tgz#2ef0bb39a24ac034787965c457368a28730e220a" + integrity sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA== + dependencies: + node-fetch "^2.6.7" + whatwg-fetch "^2.0.4" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-eql@^4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" + integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== + dependencies: + type-detect "^4.0.0" + +deep-equal@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +deferred-leveldown@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" + integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== + dependencies: + abstract-leveldown "~2.6.0" + +deferred-leveldown@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" + integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== + dependencies: + abstract-leveldown "~5.0.0" + inherits "^2.0.3" + +define-properties@^1.1.3, define-properties@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" + integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +delete-empty@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/delete-empty/-/delete-empty-3.0.0.tgz#f8040f2669f26fa7060bc2304e9859c593b685e8" + integrity sha512-ZUyiwo76W+DYnKsL3Kim6M/UOavPdBJgDYWOmuQhYaZvJH0AXAHbUNyEDtRbBra8wqqr686+63/0azfEk1ebUQ== + dependencies: + ansi-colors "^4.1.0" + minimist "^1.2.0" + path-starts-with "^2.0.0" + rimraf "^2.6.2" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A== + dependencies: + repeating "^2.0.0" + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +dotenv@^16.0.0: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + +dotignore@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" + integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== + dependencies: + minimatch "^3.0.4" + +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.3.47: + version "1.4.319" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.319.tgz#75cfecf8bc4522d1450713db1f2096fe73991cdb" + integrity sha512-WeoI6NwZUgteKB+Wmn692S35QycwwNxwgTomNnoCJ79znBAjtBi6C/cIW62JkXmpJRX5rKNYSLDBdAM8l5fH0w== + +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encode-utf8@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding-down@5.0.4, encoding-down@~5.0.0: + version "5.0.4" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" + integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== + dependencies: + abstract-leveldown "^5.0.0" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + xtend "^4.0.1" + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enquirer@^2.3.0: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.21.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6" + integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.4" + is-array-buffer "^3.0.1" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.10" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eth-block-tracker@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" + integrity sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug== + dependencies: + eth-query "^2.1.0" + ethereumjs-tx "^1.3.3" + ethereumjs-util "^5.1.3" + ethjs-util "^0.1.3" + json-rpc-engine "^3.6.0" + pify "^2.3.0" + tape "^4.6.3" + +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + +eth-json-rpc-infura@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" + integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== + dependencies: + cross-fetch "^2.1.1" + eth-json-rpc-middleware "^1.5.0" + json-rpc-engine "^3.4.0" + json-rpc-error "^2.0.0" + +eth-json-rpc-middleware@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" + integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q== + dependencies: + async "^2.5.0" + eth-query "^2.1.2" + eth-tx-summary "^3.1.2" + ethereumjs-block "^1.6.0" + ethereumjs-tx "^1.3.3" + ethereumjs-util "^5.1.2" + ethereumjs-vm "^2.1.0" + fetch-ponyfill "^4.0.0" + json-rpc-engine "^3.6.0" + json-rpc-error "^2.0.0" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + tape "^4.6.3" + +eth-lib@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" + integrity sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA== + dependencies: + json-rpc-random-id "^1.0.0" + xtend "^4.0.1" + +eth-sig-util@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-3.0.0.tgz#75133b3d7c20a5731af0690c385e184ab942b97e" + integrity sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ== + dependencies: + buffer "^5.2.1" + elliptic "^6.4.0" + ethereumjs-abi "0.6.5" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.0" + tweetnacl-util "^0.15.0" + +eth-sig-util@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" + integrity sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw== + dependencies: + ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" + ethereumjs-util "^5.1.1" + +eth-tx-summary@^3.1.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" + integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg== + dependencies: + async "^2.1.2" + clone "^2.0.0" + concat-stream "^1.5.1" + end-of-stream "^1.1.0" + eth-query "^2.0.2" + ethereumjs-block "^1.4.1" + ethereumjs-tx "^1.1.1" + ethereumjs-util "^5.0.1" + ethereumjs-vm "^2.6.0" + through2 "^2.0.3" + +ethashjs@~0.0.7: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.8.tgz#227442f1bdee409a548fb04136e24c874f3aa6f9" + integrity sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw== + dependencies: + async "^2.1.2" + buffer-xor "^2.0.1" + ethereumjs-util "^7.0.2" + miller-rabin "^4.0.0" + +ethereum-bloom-filters@^1.0.6: + version "1.0.10" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" + integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + dependencies: + js-sha3 "^0.8.0" + +ethereum-common@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" + integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== + +ethereum-common@^0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" + integrity sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ== + +ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + blakejs "^1.1.0" + browserify-aes "^1.2.0" + bs58check "^2.1.2" + create-hash "^1.2.0" + create-hmac "^1.1.7" + hash.js "^1.1.7" + keccak "^3.0.0" + pbkdf2 "^3.0.17" + randombytes "^2.1.0" + safe-buffer "^5.1.2" + scrypt-js "^3.0.0" + secp256k1 "^4.0.1" + setimmediate "^1.0.5" + +ethereum-cryptography@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" + integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== + dependencies: + "@noble/hashes" "1.2.0" + "@noble/secp256k1" "1.7.1" + "@scure/bip32" "1.1.5" + "@scure/bip39" "1.1.1" + +ethereum-waffle@^3.4.0: + version "3.4.4" + resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz#1378b72040697857b7f5e8f473ca8f97a37b5840" + integrity sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q== + dependencies: + "@ethereum-waffle/chai" "^3.4.4" + "@ethereum-waffle/compiler" "^3.4.4" + "@ethereum-waffle/mock-contract" "^3.4.4" + "@ethereum-waffle/provider" "^3.4.4" + ethers "^5.0.1" + +ethereumjs-abi@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" + integrity sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g== + dependencies: + bn.js "^4.10.0" + ethereumjs-util "^4.3.0" + +ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": + version "0.6.8" + resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0" + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" + integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== + dependencies: + ethereumjs-util "^6.0.0" + rlp "^2.2.1" + safe-buffer "^5.1.1" + +ethereumjs-account@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" + integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== + dependencies: + ethereumjs-util "^5.0.0" + rlp "^2.0.0" + safe-buffer "^5.1.1" + +ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" + integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== + dependencies: + async "^2.0.1" + ethereumjs-common "^1.5.0" + ethereumjs-tx "^2.1.1" + ethereumjs-util "^5.0.0" + merkle-patricia-tree "^2.1.2" + +ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" + integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== + dependencies: + async "^2.0.1" + ethereum-common "0.2.0" + ethereumjs-tx "^1.2.2" + ethereumjs-util "^5.0.0" + merkle-patricia-tree "^2.1.2" + +ethereumjs-blockchain@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz#30f2228dc35f6dcf94423692a6902604ae34960f" + integrity sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ== + dependencies: + async "^2.6.1" + ethashjs "~0.0.7" + ethereumjs-block "~2.2.2" + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.1.0" + flow-stoplight "^1.0.0" + level-mem "^3.0.1" + lru-cache "^5.1.1" + rlp "^2.2.2" + semaphore "^1.1.0" + +ethereumjs-common@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" + integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== + +ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" + integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== + +ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" + integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== + dependencies: + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.0.0" + +ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" + integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== + dependencies: + ethereum-common "^0.0.18" + ethereumjs-util "^5.0.0" + +ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0, ethereumjs-util@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.3" + +ethereumjs-util@^4.3.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" + integrity sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w== + dependencies: + bn.js "^4.8.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + rlp "^2.0.0" + +ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" + integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== + dependencies: + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "^0.1.3" + rlp "^2.0.0" + safe-buffer "^5.1.1" + +ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0: + version "7.1.5" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" + integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + +ethereumjs-vm@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" + integrity sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA== + dependencies: + async "^2.1.2" + async-eventemitter "^0.2.2" + core-js-pure "^3.0.1" + ethereumjs-account "^3.0.0" + ethereumjs-block "^2.2.2" + ethereumjs-blockchain "^4.0.3" + ethereumjs-common "^1.5.0" + ethereumjs-tx "^2.1.2" + ethereumjs-util "^6.2.0" + fake-merkle-patricia-tree "^1.0.1" + functional-red-black-tree "^1.0.1" + merkle-patricia-tree "^2.3.2" + rustbn.js "~0.2.0" + safe-buffer "^5.1.1" + util.promisify "^1.0.0" + +ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" + integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== + dependencies: + async "^2.1.2" + async-eventemitter "^0.2.2" + ethereumjs-account "^2.0.3" + ethereumjs-block "~2.2.0" + ethereumjs-common "^1.1.0" + ethereumjs-util "^6.0.0" + fake-merkle-patricia-tree "^1.0.1" + functional-red-black-tree "^1.0.1" + merkle-patricia-tree "^2.3.2" + rustbn.js "~0.2.0" + safe-buffer "^5.1.1" + +ethereumjs-wallet@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" + integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA== + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereum-cryptography "^0.1.3" + ethereumjs-util "^6.0.0" + randombytes "^2.0.6" + safe-buffer "^5.1.2" + scryptsy "^1.2.1" + utf8 "^3.0.0" + uuid "^3.3.2" + +ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.2, ethers@^5.5.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw== + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express@^4.14.0: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fake-merkle-patricia-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" + integrity sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA== + dependencies: + checkpoint-store "^1.1.0" + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fetch-ponyfill@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" + integrity sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g== + dependencies: + node-fetch "~1.7.1" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-replace@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" + integrity sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA== + dependencies: + array-back "^1.0.4" + test-value "^2.1.0" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + +find-yarn-workspace-root@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" + integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== + dependencies: + fs-extra "^4.0.3" + micromatch "^3.1.4" + +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flow-stoplight@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" + integrity sha512-rDjbZUKpN8OYhB0IE/vY/I8UWO/602IIJEU/76Tv4LvYnwHCk0BCsvz4eRr9n+FQcri7L5cyaXOo0+/Kh4HisA== + +fmix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/fmix/-/fmix-0.1.0.tgz#c7bbf124dec42c9d191cfb947d0a9778dd986c0c" + integrity sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w== + dependencies: + imul "^1.0.0" + +follow-redirects@^1.12.1: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +for-each@^0.3.3, for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fp-ts@1.19.3: + version "1.19.3" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== + +fp-ts@^1.0.0: + version "1.19.5" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" + integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^4.0.2, fs-extra@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.0.0, fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +ganache-core@^2.13.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.2.tgz#27e6fc5417c10e6e76e2e646671869d7665814a3" + integrity sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw== + dependencies: + abstract-leveldown "3.0.0" + async "2.6.2" + bip39 "2.5.0" + cachedown "1.0.0" + clone "2.1.2" + debug "3.2.6" + encoding-down "5.0.4" + eth-sig-util "3.0.0" + ethereumjs-abi "0.6.8" + ethereumjs-account "3.0.0" + ethereumjs-block "2.2.2" + ethereumjs-common "1.5.0" + ethereumjs-tx "2.1.2" + ethereumjs-util "6.2.1" + ethereumjs-vm "4.2.0" + heap "0.2.6" + keccak "3.0.1" + level-sublevel "6.6.4" + levelup "3.1.1" + lodash "4.17.20" + lru-cache "5.1.1" + merkle-patricia-tree "3.0.0" + patch-package "6.2.2" + seedrandom "3.0.1" + source-map-support "0.5.12" + tmp "0.1.0" + web3-provider-engine "14.2.1" + websocket "1.0.32" + optionalDependencies: + ethereumjs-wallet "0.6.5" + web3 "1.2.11" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.2, glob@^7.1.3, glob@~7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +got@^11.8.5: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +hardhat-abi-exporter@^2.9.0: + version "2.10.1" + resolved "https://registry.yarnpkg.com/hardhat-abi-exporter/-/hardhat-abi-exporter-2.10.1.tgz#b14884e233c73fe3f43360f014ad7fd6df4b6d25" + integrity sha512-X8GRxUTtebMAd2k4fcPyVnCdPa6dYK4lBsrwzKP5yiSq4i+WadWPIumaLfce53TUf/o2TnLpLOduyO1ylE2NHQ== + dependencies: + "@ethersproject/abi" "^5.5.0" + delete-empty "^3.0.0" + +hardhat-preprocessor@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/hardhat-preprocessor/-/hardhat-preprocessor-0.1.5.tgz#75b22641fd6a680739c995d03bd5f7868eb72144" + integrity sha512-j8m44mmPxpxAAd0G8fPHRHOas/INZdzptSur0TNJvMEGcFdLDhbHHxBcqZVQ/bmiW42q4gC60AP4CXn9EF018g== + dependencies: + murmur-128 "^0.2.1" + +hardhat@^2.9.5: + version "2.13.0" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.13.0.tgz#d52a0ec9b733a651687e5b1c1b0ee9a11a30f3d0" + integrity sha512-ZlzBOLML1QGlm6JWyVAG8lVTEAoOaVm1in/RU2zoGAnYEoD1Rp4T+ZMvrLNhHaaeS9hfjJ1gJUBfiDr4cx+htQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-blockchain" "^6.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-evm" "^1.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-statemanager" "^1.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@nomicfoundation/ethereumjs-vm" "^6.0.0" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + abort-controller "^3.0.0" + adm-zip "^0.4.16" + aggregate-error "^3.0.0" + ansi-escapes "^4.3.0" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + ethereum-cryptography "^1.0.3" + ethereumjs-abi "^0.6.8" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "7.2.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + keccak "^3.0.2" + lodash "^4.17.11" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + qs "^6.7.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3, has@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +heap@0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" + integrity sha512-MzzWcnfB1e4EG2vHi3dXHoBupmuXNZzx6pY6HldVS55JKKBoq3xOyzfSaZRkJp37HIhEYC78knabHff3zc4dQQ== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.13, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +immediate@~3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + integrity sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg== + +immutable@^4.0.0-rc.12: + version "4.2.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.4.tgz#83260d50889526b4b531a5e293709a77f7c55a2a" + integrity sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w== + +imul@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9" + integrity sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internal-slot@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + +io-ts@1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== + dependencies: + fp-ts "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" + integrity sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" + integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== + dependencies: + async "^2.0.1" + babel-preset-env "^1.7.0" + babelify "^7.3.0" + json-rpc-error "^2.0.0" + promise-to-callback "^1.0.0" + safe-event-emitter "^1.0.1" + +json-rpc-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" + integrity sha512-EwUeWP+KgAZ/xqFpaP6YDAXMtCJi+o/QQpCQFIYyxr01AdADi2y413eM8hSqJcoQym9WMePAJWoaODEJufC4Ug== + dependencies: + inherits "^2.0.1" + +json-rpc-random-id@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" + integrity sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz#e06f23128e0bbe342dc996ed5a19e28b57b580e0" + integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== + dependencies: + jsonify "^0.0.1" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw== + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +keccak@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +keccak@^3.0.0, keccak@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" + integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +keyv@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" + integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== + dependencies: + json-buffer "3.0.1" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== + optionalDependencies: + graceful-fs "^4.1.9" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +level-codec@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" + integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== + dependencies: + buffer "^5.6.0" + +level-codec@~7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" + integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== + +level-errors@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" + integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== + dependencies: + errno "~0.1.1" + +level-errors@^2.0.0, level-errors@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== + dependencies: + errno "~0.1.1" + +level-errors@~1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" + integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== + dependencies: + errno "~0.1.1" + +level-iterator-stream@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" + integrity sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.5" + xtend "^4.0.0" + +level-iterator-stream@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" + integrity sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw== + dependencies: + inherits "^2.0.1" + level-errors "^1.0.3" + readable-stream "^1.0.33" + xtend "^4.0.0" + +level-iterator-stream@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" + integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.3.6" + xtend "^4.0.0" + +level-mem@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" + integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== + dependencies: + level-packager "~4.0.0" + memdown "~3.0.0" + +level-packager@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" + integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== + dependencies: + encoding-down "~5.0.0" + levelup "^3.0.0" + +level-post@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" + integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== + dependencies: + ltgt "^2.1.2" + +level-sublevel@6.6.4: + version "6.6.4" + resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" + integrity sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA== + dependencies: + bytewise "~1.1.0" + level-codec "^9.0.0" + level-errors "^2.0.0" + level-iterator-stream "^2.0.3" + ltgt "~2.1.1" + pull-defer "^0.2.2" + pull-level "^2.0.3" + pull-stream "^3.6.8" + typewiselite "~1.0.0" + xtend "~4.0.0" + +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + +level-ws@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" + integrity sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw== + dependencies: + readable-stream "~1.0.15" + xtend "~2.1.1" + +level-ws@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" + integrity sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q== + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.8" + xtend "^4.0.1" + +level@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" + integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== + dependencies: + browser-level "^1.0.1" + classic-level "^1.2.0" + +levelup@3.1.1, levelup@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" + integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== + dependencies: + deferred-leveldown "~4.0.0" + level-errors "~2.0.0" + level-iterator-stream "~3.0.0" + xtend "~4.0.0" + +levelup@^1.2.1: + version "1.3.9" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" + integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== + dependencies: + deferred-leveldown "~1.2.1" + level-codec "~7.0.0" + level-errors "~1.0.3" + level-iterator-stream "~1.3.0" + prr "~1.0.1" + semver "~5.4.1" + xtend "~4.0.0" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + +lodash@4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +looper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" + integrity sha512-6DzMHJcjbQX/UPHc1rRCBfKlLwDkvuGZ715cIR36wSdYqWXFT35uLXq5P/2orl3tz+t+VOVPxw4yPinQlUDGDQ== + +looper@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" + integrity sha512-LJ9wplN/uSn72oJRsXTx+snxPet5c8XiZmOKCm906NVYu+ag6SB6vUcnJcWxgnl2NfbIyeobAn7Bwv6xRj2XJg== + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loupe@^2.3.1: + version "2.3.6" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" + integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== + dependencies: + get-func-name "^2.0.0" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@5.1.1, lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" + integrity sha512-91gyOKTc2k66UG6kHiH4h3S2eltcPwE1STVfMYC/NG+nZwf8IIuiamfmpGZjpbbxzSyEJaLC0tNSmhjlQUTJow== + dependencies: + pseudomap "^1.0.1" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== + +ltgt@^2.1.2, ltgt@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA== + +ltgt@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" + integrity sha512-5VjHC5GsENtIi5rbJd+feEpDKhfr7j0odoUR2Uh978g+2p93nd5o34cTjQWohXsPsCZeqoDnIqEf88mPCe0Pfw== + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + +mcl-wasm@^0.7.1: + version "0.7.9" + resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" + integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memdown@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" + integrity sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w== + dependencies: + abstract-leveldown "~2.7.1" + functional-red-black-tree "^1.0.1" + immediate "^3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.1.1" + +memdown@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" + integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== + dependencies: + abstract-leveldown "~5.0.0" + functional-red-black-tree "~1.0.1" + immediate "~3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.1.1" + +memory-level@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" + integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== + dependencies: + abstract-level "^1.0.0" + functional-red-black-tree "^1.0.1" + module-error "^1.0.1" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merkle-patricia-tree@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" + integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== + dependencies: + async "^2.6.1" + ethereumjs-util "^5.2.0" + level-mem "^3.0.1" + level-ws "^1.0.0" + readable-stream "^3.0.6" + rlp "^2.0.0" + semaphore ">=1.0.1" + +merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" + integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== + dependencies: + async "^1.4.2" + ethereumjs-util "^5.0.0" + level-ws "0.0.0" + levelup "^1.2.1" + memdown "^1.0.0" + readable-stream "^2.0.0" + rlp "^2.0.0" + semaphore ">=1.0.1" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.6, minimist@~1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== + dependencies: + mkdirp "*" + +mkdirp@*: + version "2.1.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.4.tgz#34faf1f2a1b4cc9a65a84e2979087211da608d11" + integrity sha512-Cy9cV4pRSl1o10i1dURTuRt4T04l0DkS1WZrT+Jir886OqOVkSv4FbOA7pgjhS8kEUrmm4kCRvv5var2iOCxpA== + +mkdirp@^0.5.1, mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mnemonist@^0.38.0: + version "0.38.5" + resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" + integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== + dependencies: + obliterator "^2.0.0" + +mocha@^10.0.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mock-fs@^4.1.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" + integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== + +module-error@^1.0.1, module-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^0.5.5: + version "0.5.7" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== + dependencies: + varint "^5.0.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + +multihashes@^0.4.15, multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + +murmur-128@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" + integrity sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg== + dependencies: + encode-utf8 "^1.0.2" + fmix "^0.1.0" + imul "^1.0.0" + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + +node-fetch@^2.6.1, node-fetch@^2.6.7: + version "2.6.9" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" + integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@~1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + +nofilter@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" + integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.0.0, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.12.2, object-inspect@^1.9.0, object-inspect@~1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.1.1: + version "2.1.5" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" + integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== + dependencies: + array.prototype.reduce "^1.0.5" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + +obliterator@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" + integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== + +oboe@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" + integrity sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ== + dependencies: + http-https "^1.0.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +open@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-headers@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +patch-package@6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" + integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^2.4.2" + cross-spawn "^6.0.5" + find-yarn-workspace-root "^1.2.1" + fs-extra "^7.0.1" + is-ci "^2.0.0" + klaw-sync "^6.0.0" + minimist "^1.2.0" + rimraf "^2.6.3" + semver "^5.6.0" + slash "^2.0.0" + tmp "^0.0.33" + +patch-package@^6.2.2: + version "6.5.1" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.1.tgz#3e5d00c16997e6160291fee06a521c42ac99b621" + integrity sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + cross-spawn "^6.0.5" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + is-ci "^2.0.0" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^5.6.0" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^1.10.2" + +path-browserify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-starts-with@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-starts-with/-/path-starts-with-2.0.0.tgz#ffd6d51926cd497022b44d392196033d5451892f" + integrity sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +postinstall-postinstall@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" + integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== + +precond@0.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" + integrity sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ== + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + +prettier-plugin-solidity@^1.0.0-beta.19: + version "1.1.3" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" + integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + dependencies: + "@solidity-parser/parser" "^0.16.0" + semver "^7.3.8" + solidity-comments-extractor "^0.0.7" + +prettier@^2.1.2, prettier@^2.3.1, prettier@^2.6.2: + version "2.8.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" + integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +promise-to-callback@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" + integrity sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA== + dependencies: + is-fn "^1.0.0" + set-immediate-shim "^1.0.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pull-cat@^1.1.9: + version "1.1.11" + resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" + integrity sha512-i3w+xZ3DCtTVz8S62hBOuNLRHqVDsHMNZmgrZsjPnsxXUgbWtXEee84lo1XswE7W2a3WHyqsNuDJTjVLAQR8xg== + +pull-defer@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" + integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== + +pull-level@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" + integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== + dependencies: + level-post "^1.0.7" + pull-cat "^1.1.9" + pull-live "^1.0.1" + pull-pushable "^2.0.0" + pull-stream "^3.4.0" + pull-window "^2.1.4" + stream-to-pull-stream "^1.7.1" + +pull-live@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" + integrity sha512-tkNz1QT5gId8aPhV5+dmwoIiA1nmfDOzJDlOOUpU5DNusj6neNd3EePybJ5+sITr2FwyCs/FVpx74YMCfc8YeA== + dependencies: + pull-cat "^1.1.9" + pull-stream "^3.4.0" + +pull-pushable@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" + integrity sha512-M7dp95enQ2kaHvfCt2+DJfyzgCSpWVR2h2kWYnVsW6ZpxQBx5wOu0QWOvQPVoPnBLUZYitYP2y7HyHkLQNeGXg== + +pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: + version "3.7.0" + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.7.0.tgz#85de0e44ff38a4d2ad08cc43fc458e1922f9bf0b" + integrity sha512-Eco+/R004UaCK2qEDE8vGklcTG2OeZSVm1kTUQNrykEjDwcFXDZhygFDsW49DbXyJMEhHeRL3z5cRVqPAhXlIw== + +pull-window@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" + integrity sha512-cbDzN76BMlcGG46OImrgpkMf/VkCnupj8JhsrpBw3aWBM9ye345aYnqitmZCgauBkc0HbbRRn9hCnsa3k2FNUg== + dependencies: + looper "^2.0.0" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +qs@6.11.0, qs@^6.7.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + +queue-microtask@^1.2.2, queue-microtask@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.5.2, raw-body@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^1.0.33: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.1.tgz#f9f9b5f536920253b3d26e7660e7da4ccff9bb62" + integrity sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.0.15: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + +regenerate@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ== + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g== + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw== + dependencies: + jsesc "~0.5.0" + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== + dependencies: + is-finite "^1.0.0" + +request@^2.79.0, request@^2.85.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== + +require-from-string@^2.0.0, require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +resolve@^1.10.0, resolve@^1.8.1, resolve@~1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w== + dependencies: + through "~2.3.4" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.2.8, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4: + version "2.2.7" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== + dependencies: + bn.js "^5.2.0" + +run-parallel-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" + integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== + dependencies: + queue-microtask "^1.2.2" + +rustbn.js@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" + integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-event-emitter@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" + integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== + dependencies: + events "^3.0.0" + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +scryptsy@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + integrity sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw== + dependencies: + pbkdf2 "^3.0.3" + +secp256k1@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + dependencies: + elliptic "^6.5.4" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + +seedrandom@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" + integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg== + +semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" + integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + +semver@~5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ== + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^2.7.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" + integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +solc@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" + integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== + dependencies: + command-exists "^1.2.8" + commander "3.0.2" + follow-redirects "^1.12.1" + fs-extra "^0.30.0" + js-sha3 "0.8.0" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + +solc@^0.4.20: + version "0.4.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== + dependencies: + fs-extra "^0.30.0" + memorystream "^0.3.1" + require-from-string "^1.1.0" + semver "^5.3.0" + yargs "^4.7.1" + +solc@^0.6.3: + version "0.6.12" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.12.tgz#48ac854e0c729361b22a7483645077f58cba080e" + integrity sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g== + dependencies: + command-exists "^1.2.8" + commander "3.0.2" + fs-extra "^0.30.0" + js-sha3 "0.8.0" + memorystream "^0.3.1" + require-from-string "^2.0.0" + semver "^5.5.0" + tmp "0.0.33" + +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@0.5.12: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.13: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.12" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" + integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stacktrace-parser@^0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stream-to-pull-stream@^1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" + integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== + dependencies: + looper "^3.0.0" + pull-stream "^3.2.3" + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.trim@~1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== + dependencies: + is-hex-prefixed "1.0.0" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +swarm-js@^0.1.40: + version "0.1.42" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" + integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^11.8.5" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request "^1.0.1" + +table-layout@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" + +table@^6.8.0: + version "6.8.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + +tape@^4.6.3: + version "4.16.2" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.16.2.tgz#7565e6af20426565557266e9dda7215869b297b6" + integrity sha512-TUChV+q0GxBBCEbfCYkGLkv8hDJYjMdSWdE0/Lr331sB389dsvFUHNV9ph5iQqKzt8Ss9drzcda/YeexclBFqg== + dependencies: + call-bind "~1.0.2" + deep-equal "~1.1.1" + defined "~1.0.1" + dotignore "~0.1.2" + for-each "~0.3.3" + glob "~7.2.3" + has "~1.0.3" + inherits "~2.0.4" + is-regex "~1.1.4" + minimist "~1.2.7" + object-inspect "~1.12.3" + resolve "~1.22.1" + resumer "~0.0.0" + string.prototype.trim "~1.2.7" + through "~2.3.8" + +tar@^4.0.2: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + 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" + +test-value@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" + integrity sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w== + dependencies: + array-back "^1.0.3" + typical "^2.6.0" + +testrpc@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== + +through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + +tmp@0.0.33, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== + dependencies: + rimraf "^2.6.3" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw== + +ts-command-line-args@^2.2.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.4.2.tgz#b4815b23c35f8a0159d4e69e01012d95690bc448" + integrity sha512-mJLQQBOdyD4XI/ZWQY44PIdYde47JhV2xl380O7twPkTQ+Y5vFDHsk8LOeXKuz7dVY5aDCfAzRarNfSqtKOkQQ== + dependencies: + "@morgan-stanley/ts-mocking-bird" "^0.6.2" + chalk "^4.1.0" + command-line-args "^5.1.1" + command-line-usage "^6.1.0" + string-format "^2.0.0" + +ts-essentials@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" + integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== + +ts-essentials@^6.0.3: + version "6.0.7" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-6.0.7.tgz#5f4880911b7581a873783740ce8b94da163d18a6" + integrity sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw== + +ts-essentials@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== + +ts-generator@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" + integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== + dependencies: + "@types/mkdirp" "^0.5.2" + "@types/prettier" "^2.1.1" + "@types/resolve" "^0.0.8" + chalk "^2.4.1" + glob "^7.1.2" + mkdirp "^0.5.1" + prettier "^2.1.2" + resolve "^1.8.1" + ts-essentials "^1.0.0" + +ts-node@^10.7.0: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl-util@^0.15.0, tweetnacl-util@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +tweetnacl@^1.0.0, tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typechain@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-3.0.0.tgz#d5a47700831f238e43f7429b987b4bb54849b92e" + integrity sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg== + dependencies: + command-line-args "^4.0.7" + debug "^4.1.1" + fs-extra "^7.0.0" + js-sha3 "^0.8.0" + lodash "^4.17.15" + ts-essentials "^6.0.3" + ts-generator "^0.1.1" + +typechain@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.1.tgz#9c2e8012c2c4c586536fc18402dcd7034c4ff0bd" + integrity sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +typescript@^4.6.4: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +typewise-core@^1.2, typewise-core@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" + integrity sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg== + +typewise@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" + integrity sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ== + dependencies: + typewise-core "^1.2.0" + +typewiselite@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" + integrity sha512-J9alhjVHupW3Wfz6qFRGgQw0N3gr8hOkw6zm7FZ6UR1Cse/oD9/JVok7DNE9TT9IbciDHX2Ex9+ksE6cRmtymw== + +typical@^2.6.0, typical@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" + integrity sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +underscore@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + +undici@^5.14.0: + version "5.20.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.20.0.tgz#6327462f5ce1d3646bcdac99da7317f455bcc263" + integrity sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g== + dependencies: + busboy "^1.6.0" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unorm@^1.3.3: + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +utf8@3.0.0, utf8@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util.promisify@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + for-each "^0.3.3" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.1" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +web3-bzz@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" + integrity sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg== + dependencies: + "@types/node" "^12.12.6" + got "9.6.0" + swarm-js "^0.1.40" + underscore "1.9.1" + +web3-core-helpers@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99" + integrity sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A== + dependencies: + underscore "1.9.1" + web3-eth-iban "1.2.11" + web3-utils "1.2.11" + +web3-core-method@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6" + integrity sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw== + dependencies: + "@ethersproject/transactions" "^5.0.0-beta.135" + underscore "1.9.1" + web3-core-helpers "1.2.11" + web3-core-promievent "1.2.11" + web3-core-subscriptions "1.2.11" + web3-utils "1.2.11" + +web3-core-promievent@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf" + integrity sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a" + integrity sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.11" + web3-providers-http "1.2.11" + web3-providers-ipc "1.2.11" + web3-providers-ws "1.2.11" + +web3-core-subscriptions@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd" + integrity sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg== + dependencies: + eventemitter3 "4.0.4" + underscore "1.9.1" + web3-core-helpers "1.2.11" + +web3-core@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7" + integrity sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ== + dependencies: + "@types/bn.js" "^4.11.5" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-requestmanager "1.2.11" + web3-utils "1.2.11" + +web3-eth-abi@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0" + integrity sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg== + dependencies: + "@ethersproject/abi" "5.0.0-beta.153" + underscore "1.9.1" + web3-utils "1.2.11" + +web3-eth-accounts@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520" + integrity sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw== + dependencies: + crypto-browserify "3.12.0" + eth-lib "0.2.8" + ethereumjs-common "^1.3.2" + ethereumjs-tx "^2.1.1" + scrypt-js "^3.0.1" + underscore "1.9.1" + uuid "3.3.2" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-utils "1.2.11" + +web3-eth-contract@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90" + integrity sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow== + dependencies: + "@types/bn.js" "^4.11.5" + underscore "1.9.1" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-promievent "1.2.11" + web3-core-subscriptions "1.2.11" + web3-eth-abi "1.2.11" + web3-utils "1.2.11" + +web3-eth-ens@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532" + integrity sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + underscore "1.9.1" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-promievent "1.2.11" + web3-eth-abi "1.2.11" + web3-eth-contract "1.2.11" + web3-utils "1.2.11" + +web3-eth-iban@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef" + integrity sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ== + dependencies: + bn.js "^4.11.9" + web3-utils "1.2.11" + +web3-eth-personal@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70" + integrity sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-net "1.2.11" + web3-utils "1.2.11" + +web3-eth@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793" + integrity sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ== + dependencies: + underscore "1.9.1" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-subscriptions "1.2.11" + web3-eth-abi "1.2.11" + web3-eth-accounts "1.2.11" + web3-eth-contract "1.2.11" + web3-eth-ens "1.2.11" + web3-eth-iban "1.2.11" + web3-eth-personal "1.2.11" + web3-net "1.2.11" + web3-utils "1.2.11" + +web3-net@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b" + integrity sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg== + dependencies: + web3-core "1.2.11" + web3-core-method "1.2.11" + web3-utils "1.2.11" + +web3-provider-engine@14.2.1: + version "14.2.1" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" + integrity sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw== + dependencies: + async "^2.5.0" + backoff "^2.5.0" + clone "^2.0.0" + cross-fetch "^2.1.0" + eth-block-tracker "^3.0.0" + eth-json-rpc-infura "^3.1.0" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.2.2" + ethereumjs-tx "^1.2.0" + ethereumjs-util "^5.1.5" + ethereumjs-vm "^2.3.4" + json-rpc-error "^2.0.0" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + readable-stream "^2.2.9" + request "^2.85.0" + semaphore "^1.0.3" + ws "^5.1.1" + xhr "^2.2.0" + xtend "^4.0.1" + +web3-providers-http@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6" + integrity sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA== + dependencies: + web3-core-helpers "1.2.11" + xhr2-cookies "1.1.0" + +web3-providers-ipc@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21" + integrity sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ== + dependencies: + oboe "2.1.4" + underscore "1.9.1" + web3-core-helpers "1.2.11" + +web3-providers-ws@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb" + integrity sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg== + dependencies: + eventemitter3 "4.0.4" + underscore "1.9.1" + web3-core-helpers "1.2.11" + websocket "^1.0.31" + +web3-shh@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f" + integrity sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg== + dependencies: + web3-core "1.2.11" + web3-core-method "1.2.11" + web3-core-subscriptions "1.2.11" + web3-net "1.2.11" + +web3-utils@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82" + integrity sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ== + dependencies: + bn.js "^4.11.9" + eth-lib "0.2.8" + ethereum-bloom-filters "^1.0.6" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + underscore "1.9.1" + utf8 "3.0.0" + +web3-utils@^1.0.0-beta.31: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.2.tgz#c32dec5e9b955acbab220eefd7715bc540b75cc9" + integrity sha512-v7j6xhfLQfY7xQDrUP0BKbaNrmZ2/+egbqP9q3KYmOiPpnvAfol+32slgL0WX/5n8VPvKCK5EZ1HGrAVICSToA== + dependencies: + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" + integrity sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ== + dependencies: + web3-bzz "1.2.11" + web3-core "1.2.11" + web3-eth "1.2.11" + web3-eth-personal "1.2.11" + web3-net "1.2.11" + web3-shh "1.2.11" + web3-utils "1.2.11" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +websocket@1.0.32: + version "1.0.32" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" + integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +websocket@^1.0.31: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +whatwg-fetch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@7.4.6: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@^5.1.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" + integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== + dependencies: + async-limiter "~1.0.0" + +ws@^7.4.6: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +xhr-request-promise@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== + dependencies: + xhr-request "^1.1.0" + +xhr-request@^1.0.1, xhr-request@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g== + dependencies: + cookiejar "^2.1.1" + +xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== + dependencies: + global "~4.4.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ== + dependencies: + object-keys "~0.4.0" + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA== + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA== + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 6616faf6e4b9c0a363fc0d928f3647347b213ed8 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:06:18 +0000 Subject: [PATCH 032/156] forge install: openzeppelin-contracts v4.8.2 --- .gitmodules | 3 ++- lib/openzeppelin-contracts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 160000 lib/openzeppelin-contracts diff --git a/.gitmodules b/.gitmodules index 4ba61017..f9f7c92c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,7 +9,8 @@ url = https://github.com/Rari-Capital/solmate [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts + url = https://github.com/Openzeppelin/openzeppelin-contracts + branch = v4.8.2 [submodule "lib/LayerZero"] path = lib/LayerZero url = https://github.com/LayerZero-Labs/LayerZero diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 00000000..d00acef4 --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit d00acef4059807535af0bd0dd0ddf619747a044b From 020aab167be529fd5230223f6454b963faf3ba77 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:08:14 +0000 Subject: [PATCH 033/156] chore: Remove Redemption logic --- contracts/redeem/RedemptionReceiver.sol | 142 ------------------------ contracts/redeem/RedemptionSender.sol | 77 ------------- remappings.txt | 1 - 3 files changed, 220 deletions(-) delete mode 100644 contracts/redeem/RedemptionReceiver.sol delete mode 100644 contracts/redeem/RedemptionSender.sol diff --git a/contracts/redeem/RedemptionReceiver.sol b/contracts/redeem/RedemptionReceiver.sol deleted file mode 100644 index eaaa87a9..00000000 --- a/contracts/redeem/RedemptionReceiver.sol +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -import "LayerZero/interfaces/ILayerZeroEndpoint.sol"; -import "LayerZero/interfaces/ILayerZeroReceiver.sol"; -import "contracts/interfaces/IERC20.sol"; -import "contracts/interfaces/IVelo.sol"; - -/// @notice Part 2 of 2 in the WeVE (FTM) -> USDC + VELO (OP) redemption process -/// This contract is responsible for receiving the LZ message and distributing USDC + VELO -contract RedemptionReceiver is ILayerZeroReceiver { - IERC20 public immutable USDC; - IVelo public immutable VELO; - - uint16 public immutable fantomChainId; // 12 for FTM, 10012 for FTM testnet - address public immutable endpoint; - - address public team; - uint256 public immutable deployed; - - address public fantomSender; - uint256 public constant ELIGIBLE_WEVE = 375112540 * 1e18; - uint256 public redeemedWEVE; - uint256 public redeemableUSDC; - uint256 public redeemableVELO; - uint256 public leftoverVELO; - - constructor( - address _usdc, - address _velo, - uint16 _fantomChainId, - address _endpoint - ) { - require(_fantomChainId == 12 || _fantomChainId == 10012, "CHAIN_ID_NOT_FTM"); - - USDC = IERC20(_usdc); - VELO = IVelo(_velo); - - fantomChainId = _fantomChainId; - endpoint = _endpoint; - - team = msg.sender; - deployed = block.timestamp; - } - - modifier onlyTeam() { - require(msg.sender == team, "ONLY_TEAM"); - _; - } - - event Initialized(address fantomSender, uint256 redeemableUSDC, uint256 redeemableVELO); - - function initializeReceiverWith( - address _fantomSender, - uint256 _redeemableUSDC, - uint256 _redeemableVELO - ) external onlyTeam { - require(fantomSender == address(0), "ALREADY_INITIALIZED"); - require( - USDC.transferFrom(msg.sender, address(this), _redeemableUSDC), - "USDC_TRANSFER_FAILED" - ); - - fantomSender = _fantomSender; - redeemableUSDC = _redeemableUSDC; - redeemableVELO = _redeemableVELO; - leftoverVELO = _redeemableVELO; - - emit Initialized(fantomSender, redeemableUSDC, redeemableVELO); - } - - function setTeam(address _team) external onlyTeam { - team = _team; - } - - function previewRedeem(uint256 amountWEVE) - public - view - returns (uint256 shareOfUSDC, uint256 shareOfVELO) - { - // pro rata USDC - shareOfUSDC = (amountWEVE * redeemableUSDC) / ELIGIBLE_WEVE; - // pro rata VELO - shareOfVELO = (amountWEVE * redeemableVELO) / ELIGIBLE_WEVE; - } - - function lzReceive( - uint16 srcChainId, - bytes memory srcAddress, - uint64, - bytes memory payload - ) external override { - require(fantomSender != address(0), "NOT_INITIALIZED"); - require( - msg.sender == endpoint && - srcChainId == fantomChainId && - addressFromPackedBytes(srcAddress) == fantomSender, - "UNAUTHORIZED_CALLER" - ); - - (address redemptionAddress, uint256 amountWEVE) = abi.decode( - payload, - (address, uint256) - ); - - require( - (redeemedWEVE += amountWEVE) <= ELIGIBLE_WEVE, - "cannot redeem more than eligible" - ); - (uint256 shareOfUSDC, uint256 shareOfVELO) = previewRedeem(amountWEVE); - - require( - USDC.transfer(redemptionAddress, shareOfUSDC), - "USDC_TRANSFER_FAILED" - ); - - leftoverVELO -= shareOfVELO; // this will revert if underflows - require( - VELO.claim(redemptionAddress, shareOfVELO), - "CLAIM_FAILED" - ); - } - - function addressFromPackedBytes(bytes memory toAddressBytes) - public - pure - returns (address toAddress) - { - // solhint-disable-next-line no-inline-assembly - assembly { - toAddress := mload(add(toAddressBytes, 20)) - } - } - - function claimLeftovers() external onlyTeam { - require(block.timestamp >= deployed + 30 days, "LEFTOVERS_NOT_CLAIMABLE"); - require( - USDC.transfer(msg.sender, USDC.balanceOf(address(this))), - "USDC_TRANSFER_FAILED" - ); - } -} diff --git a/contracts/redeem/RedemptionSender.sol b/contracts/redeem/RedemptionSender.sol deleted file mode 100644 index 0c1cc1b7..00000000 --- a/contracts/redeem/RedemptionSender.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -import "LayerZero/interfaces/ILayerZeroEndpoint.sol"; -import "contracts/interfaces/IERC20.sol"; - -/// @notice Part 1 of 2 in the WeVE (FTM) -> USDC + VELO (OP) redemption process -/// This contract is responsible for burning WeVE and sending the LZ message -contract RedemptionSender { - address public immutable weve; - uint256 public constant ELIGIBLE_WEVE = 375112540 * 1e18; - uint256 public redeemedWEVE; - uint16 public immutable optimismChainId; // 11 for OP, 10011 for OP Kovan - address public immutable endpoint; - address public immutable optimismReceiver; - - event SubmittedClaim(uint256 amount, uint64 indexed lzeNonce); - - constructor( - address _weve, - uint16 _optimismChainId, - address _endpoint, - address _optimismReceiver - ) { - require(_optimismChainId == 11 || _optimismChainId == 10011, "CHAIN_ID_NOT_OP"); - weve = _weve; - optimismChainId = _optimismChainId; - endpoint = _endpoint; - optimismReceiver = _optimismReceiver; - } - - function estimateLayerZeroFee() public view returns (uint256 ftm, uint256 lzo) { - (ftm, lzo) = ILayerZeroEndpoint(endpoint).estimateFees( - optimismChainId, - address(this), - abi.encode(msg.sender, 42690), - false, - bytes("") - ); - } - - function redeemWEVE( - uint256 amount, - address zroPaymentAddress, - bytes memory zroTransactionParams - ) public payable { - require(amount != 0, "AMOUNT_ZERO"); - require( - (redeemedWEVE += amount) <= ELIGIBLE_WEVE, - "cannot redeem more than eligible" - ); - require( - IERC20(weve).transferFrom( - msg.sender, - 0x000000000000000000000000000000000000dEaD, - amount - ), - "WEVE: TRANSFER_FAILED" - ); - - ILayerZeroEndpoint(endpoint).send{value: msg.value}( - optimismChainId, - abi.encodePacked(optimismReceiver), - abi.encode(msg.sender, amount), - payable(msg.sender), - zroPaymentAddress, - zroTransactionParams - ); - - uint64 nonce = ILayerZeroEndpoint(endpoint).getOutboundNonce( - optimismChainId, - address(this) - ); - - emit SubmittedClaim(amount, nonce); - } -} diff --git a/remappings.txt b/remappings.txt index 07342fae..e5a98e9d 100644 --- a/remappings.txt +++ b/remappings.txt @@ -2,5 +2,4 @@ ds-test/=lib/ds-test/src/ forge-std/=lib/forge-std/src/ solmate/=lib/solmate/src/ openzeppelin-contracts/=lib/openzeppelin-contracts/ -LayerZero/=lib/LayerZero/contracts/ utils/=test/utils/ From d3f20bd888dfe646b5b8f3fed87de50b22e2ee3e Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:14:45 +0000 Subject: [PATCH 034/156] chore: Drop cross-chain redemption logic --- .env.example | 1 - contracts/Velo.sol | 18 ---- contracts/redeem/MerkleClaim.sol | 70 ------------ hardhat.config.ts | 6 -- readme.md | 7 +- tasks/deploy/constants/fantomConfig.ts | 7 -- tasks/deploy/constants/testFantomConfig.ts | 7 -- tasks/deploy/ftm.ts | 45 -------- tasks/deploy/index.ts | 4 +- tasks/deploy/init.ts | 40 ------- tasks/deploy/op.ts | 39 +------ test/BaseTest.sol | 3 - test/Redeem.t.sol | 117 --------------------- test/utils/TestEndpoint.sol | 45 -------- test/utils/TestOwner.sol | 9 -- 15 files changed, 4 insertions(+), 414 deletions(-) delete mode 100644 contracts/redeem/MerkleClaim.sol delete mode 100644 tasks/deploy/constants/fantomConfig.ts delete mode 100644 tasks/deploy/constants/testFantomConfig.ts delete mode 100644 tasks/deploy/ftm.ts delete mode 100644 tasks/deploy/init.ts delete mode 100644 test/Redeem.t.sol delete mode 100644 test/utils/TestEndpoint.sol diff --git a/.env.example b/.env.example index f0ed142b..a52aa00c 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,3 @@ PRIVATE_KEY= OP_SCAN_API_KEY= -FTM_SCAN_API_KEY= ALCHEMY_API_KEY= \ No newline at end of file diff --git a/contracts/Velo.sol b/contracts/Velo.sol index b7e3c839..07b6abed 100644 --- a/contracts/Velo.sol +++ b/contracts/Velo.sol @@ -15,8 +15,6 @@ contract Velo is IVelo { bool public initialMinted; address public minter; - address public redemptionReceiver; - address public merkleClaim; event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); @@ -32,16 +30,6 @@ contract Velo is IVelo { minter = _minter; } - function setRedemptionReceiver(address _receiver) external { - require(msg.sender == minter); - redemptionReceiver = _receiver; - } - - function setMerkleClaim(address _merkleClaim) external { - require(msg.sender == minter); - merkleClaim = _merkleClaim; - } - // NFTs are minted from this amount as well now function initialMint(address _recipient) external { require(msg.sender == minter && !initialMinted); @@ -90,10 +78,4 @@ contract Velo is IVelo { _mint(account, amount); return true; } - - function claim(address account, uint amount) external returns (bool) { - require(msg.sender == redemptionReceiver || msg.sender == merkleClaim); - _mint(account, amount); - return true; - } } diff --git a/contracts/redeem/MerkleClaim.sol b/contracts/redeem/MerkleClaim.sol deleted file mode 100644 index 6883ce58..00000000 --- a/contracts/redeem/MerkleClaim.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.13; - -/// ============ Imports ============ - -import {IVelo} from "contracts/interfaces/IVelo.sol"; -import {MerkleProof} from "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol"; // OZ: MerkleProof - -/// @title MerkleClaim -/// @notice Claims VELO for members of a merkle tree -/// @author Modified from Merkle Airdrop Starter (https://github.com/Anish-Agnihotri/merkle-airdrop-starter/blob/master/contracts/src/MerkleClaimERC20.sol) -contract MerkleClaim { - /// ============ Immutable storage ============ - - /// @notice VELO token to claim - IVelo public immutable VELO; - /// @notice ERC20-claimee inclusion root - bytes32 public immutable merkleRoot; - - /// ============ Mutable storage ============ - - /// @notice Mapping of addresses who have claimed tokens - mapping(address => bool) public hasClaimed; - - /// ============ Constructor ============ - - /// @notice Creates a new MerkleClaim contract - /// @param _velo address - /// @param _merkleRoot of claimees - constructor(address _velo, bytes32 _merkleRoot) { - VELO = IVelo(_velo); - merkleRoot = _merkleRoot; - } - - /// ============ Events ============ - - /// @notice Emitted after a successful token claim - /// @param to recipient of claim - /// @param amount of tokens claimed - event Claim(address indexed to, uint256 amount); - - /// ============ Functions ============ - - /// @notice Allows claiming tokens if address is part of merkle tree - /// @param to address of claimee - /// @param amount of tokens owed to claimee - /// @param proof merkle proof to prove address and amount are in tree - function claim( - address to, - uint256 amount, - bytes32[] calldata proof - ) external { - // Throw if address has already claimed tokens - require(!hasClaimed[to], "ALREADY_CLAIMED"); - - // Verify merkle proof, or revert if not in tree - bytes32 leaf = keccak256(abi.encodePacked(to, amount)); - bool isValidLeaf = MerkleProof.verify(proof, merkleRoot, leaf); - require(isValidLeaf, "NOT_IN_MERKLE"); - - // Set address to claimed - hasClaimed[to] = true; - - // Claim tokens for address - require(VELO.claim(to, amount), "CLAIM_FAILED"); - - // Emit claim event - emit Claim(to, amount); - } -} diff --git a/hardhat.config.ts b/hardhat.config.ts index ef75274c..05d19884 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -35,10 +35,6 @@ const config: HardhatUserConfig = { url: "https://rpc.fantom.network", accounts: [process.env.PRIVATE_KEY!], }, - ftmTestnet: { - url: "https://rpc.testnet.fantom.network", - accounts: [process.env.PRIVATE_KEY!], - }, optimisticEthereum: { url: "https://mainnet.optimism.io", accounts: [process.env.PRIVATE_KEY!], @@ -77,8 +73,6 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: { - opera: process.env.FTM_SCAN_API_KEY!, - ftmTestnet: process.env.FTM_SCAN_API_KEY!, optimisticEthereum: process.env.OP_SCAN_API_KEY!, optimisticKovan: process.env.OP_SCAN_API_KEY!, } diff --git a/readme.md b/readme.md index 402b037e..6afe5d2c 100644 --- a/readme.md +++ b/readme.md @@ -27,9 +27,7 @@ This project's deployment process uses [Hardhat tasks](https://hardhat.org/guide Deployment contains 3 steps: -1. `npx hardhat deploy:op` which deploys the core contracts, along with RedemptionReceiver, to Optimism. - -2. `npx hardhat deploy:ftm` which deploys the RedemptionSender contract to Fantom. The RedemptionReceiver address from Step 1 should be recorded in `deployed.ts` prior. +1. `npx hardhat deploy:op` which deploys the core contracts to Optimism. ## Security @@ -41,9 +39,6 @@ The Velodrome team engaged with Code 4rena for a security review. The results of | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ | | WETH | [0x4200000000000000000000000000000000000006](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000006#code) | | Velo | [0x3c8B650257cFb5f272f799F5e2b4e65093a11a05](https://optimistic.etherscan.io/address/0x3c8B650257cFb5f272f799F5e2b4e65093a11a05#code) | -| MerkleClaim | [0x00D59BC35174C3b250Dd92a363495d38C8777a49](https://optimistic.etherscan.io/address/0x00D59BC35174C3b250Dd92a363495d38C8777a49#code) | -| RedemptionSender | [0x9809fB94eED086F9529df00d6f125Bf25Ee84A93](https://ftmscan.com/address/0x9809fB94eED086F9529df00d6f125Bf25Ee84A93#code) | -| RedemptionReceiver | [0x846e822e9a00669dcC647079d7d625d2cd25A951](https://optimistic.etherscan.io/address/0x846e822e9a00669dcC647079d7d625d2cd25A951#code) | | PairFactory | [0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746](https://optimistic.etherscan.io/address/0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746#code) | | BribeFactory | [0xA84EA94Aa705F7d009CDDF2a60f65c0d446b748E](https://optimistic.etherscan.io/address/0xA84EA94Aa705F7d009CDDF2a60f65c0d446b748E#code) | | GaugeFactory | [0xC5be2c918EB04B091962fDF095A217A55CFA42C5](https://optimistic.etherscan.io/address/0xC5be2c918EB04B091962fDF095A217A55CFA42C5#code) | diff --git a/tasks/deploy/constants/fantomConfig.ts b/tasks/deploy/constants/fantomConfig.ts deleted file mode 100644 index 76ed1e25..00000000 --- a/tasks/deploy/constants/fantomConfig.ts +++ /dev/null @@ -1,7 +0,0 @@ -const fantomConfig = { - lzChainId: 12, - lzEndpoint: "0xb6319cC6c8c27A8F5dAF0dD3DF91EA35C4720dd7", - WEVE: "0x911da02C1232A3c3E1418B834A311921143B04d7", -}; - -export default fantomConfig; diff --git a/tasks/deploy/constants/testFantomConfig.ts b/tasks/deploy/constants/testFantomConfig.ts deleted file mode 100644 index 9014f713..00000000 --- a/tasks/deploy/constants/testFantomConfig.ts +++ /dev/null @@ -1,7 +0,0 @@ -const testFantomConfig = { - lzChainId: 10012, - lzEndpoint: "0x7dcAD72640F835B0FA36EFD3D6d3ec902C7E5acf", - WEVE: "0xb824b106FC861860Fc2f2E9eE83f7616074f2Dca", -}; - -export default testFantomConfig; diff --git a/tasks/deploy/ftm.ts b/tasks/deploy/ftm.ts deleted file mode 100644 index 469145ee..00000000 --- a/tasks/deploy/ftm.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { task } from "hardhat/config"; - -import optimismConfig from "./constants/optimismConfig"; -import testOptimismConfig from "./constants/testOptimismConfig"; - -import fantomConfig from "./constants/fantomConfig"; -import testFantomConfig from "./constants/testFantomConfig"; - -import deployed from "./constants/deployed"; - -task("deploy:ftm", "Deploys Fantom contracts").setAction(async function ( - taskArguments, - { ethers } -) { - const mainnet = false; - - const OP_CONFIG = mainnet ? optimismConfig : testOptimismConfig; - const FTM_CONFIG = mainnet ? fantomConfig : testFantomConfig; - - // CHECK that optimismReceiver is not empty for network - if (deployed.optimismReceiver.length === 0) { - throw "receiver not set"; - } - - // Load - const RedemptionSender = await ethers.getContractFactory("RedemptionSender"); - - // Deploy - const sender = await RedemptionSender.deploy( - FTM_CONFIG.WEVE, - OP_CONFIG.lzChainId, - FTM_CONFIG.lzEndpoint, - deployed.optimismReceiver - ); - console.log("RedemptionSender deployed to: ", sender.address); - console.log("Args: ", - FTM_CONFIG.WEVE, - OP_CONFIG.lzChainId, - FTM_CONFIG.lzEndpoint, - deployed.optimismReceiver, - "\n" - ); - - console.log("Fantom contracts deployed"); -}); diff --git a/tasks/deploy/index.ts b/tasks/deploy/index.ts index 2be5165e..25140d76 100644 --- a/tasks/deploy/index.ts +++ b/tasks/deploy/index.ts @@ -1,3 +1 @@ -import "./op.ts"; -import "./ftm.ts"; -import "./init.ts"; \ No newline at end of file +import "./op.ts"; \ No newline at end of file diff --git a/tasks/deploy/init.ts b/tasks/deploy/init.ts deleted file mode 100644 index 89d8fe44..00000000 --- a/tasks/deploy/init.ts +++ /dev/null @@ -1,40 +0,0 @@ -// The tasks in this file should be called by the multisig -// CURRENTLY OUTDATED - -// import { task } from "hardhat/config"; -// import deployed from "./constants/deployed"; - -// task("deploy:init", "Initializes RedemptionSender on Optimism").setAction( -// async function (taskArguments, { ethers }) { -// // Define network -// const network = "optimism-kovan"; // "optimism" for mainnet deploy - -// // PERFORM CHECKS ON ARGS - -// // TODO move -// const TOKEN_DECIMALS = ethers.BigNumber.from("10").pow( -// ethers.BigNumber.from("18") -// ); -// const ELIGIBLE_WEVE = -// ethers.BigNumber.from("375112540").mul(TOKEN_DECIMALS); // TODO fix rounding - -// const REDEEMABLE_USDC = ethers.BigNumber.from("0"); // TODO update -// const REDEEMABLE_VELO = -// ethers.BigNumber.from("108000000").mul(TOKEN_DECIMALS); // TODO fix rounding - -// // Load -// const RedemptionReceiver = await ethers.getContractFactory( -// "RedemptionReceiver" -// ); -// const receiver = await RedemptionReceiver.attach(deployed.optimismReceiver); - -// // Initialize -// await receiver.initializeReceiverWith( -// deployed.fantomSender, -// ELIGIBLE_WEVE, -// REDEEMABLE_USDC, -// REDEEMABLE_VELO -// ); -// console.log(`RedemptionSender at ${receiver.address} configured!`); -// } -// ); diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index e6fecd13..a0e6751e 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -3,9 +3,6 @@ import { task } from "hardhat/config"; import optimismConfig from "./constants/optimismConfig"; import testOptimismConfig from "./constants/testOptimismConfig"; -import fantomConfig from "./constants/fantomConfig"; -import testFantomConfig from "./constants/testFantomConfig"; - task("deploy:op", "Deploys Optimism contracts").setAction(async function ( taskArguments, { ethers } @@ -13,7 +10,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( const mainnet = false; const OP_CONFIG = mainnet ? optimismConfig : testOptimismConfig; - const FTM_CONFIG = mainnet ? fantomConfig : testFantomConfig; // Load const [ @@ -29,8 +25,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( Voter, Minter, VeloGovernor, - RedemptionReceiver, - MerkleClaim, ] = await Promise.all([ ethers.getContractFactory("Velo"), ethers.getContractFactory("GaugeFactory"), @@ -44,8 +38,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ethers.getContractFactory("Voter"), ethers.getContractFactory("Minter"), ethers.getContractFactory("VeloGovernor"), - ethers.getContractFactory("RedemptionReceiver"), - ethers.getContractFactory("MerkleClaim"), ]); const velo = await Velo.deploy(); @@ -96,7 +88,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ); await voter.deployed(); console.log("Voter deployed to: ", voter.address); - console.log("Args: ", + console.log("Args: ", escrow.address, pairFactory.address, gaugeFactory.address, @@ -111,50 +103,23 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ); await minter.deployed(); console.log("Minter deployed to: ", minter.address); - console.log("Args: ", + console.log("Args: ", voter.address, escrow.address, distributor.address, "\n" ); - const receiver = await RedemptionReceiver.deploy( - OP_CONFIG.USDC, - velo.address, - FTM_CONFIG.lzChainId, - OP_CONFIG.lzEndpoint, - ); - await receiver.deployed(); - console.log("RedemptionReceiver deployed to: ", receiver.address); - console.log("Args: ", - OP_CONFIG.USDC, - velo.address, - FTM_CONFIG.lzChainId, - OP_CONFIG.lzEndpoint, - "\n" - ); - const governor = await VeloGovernor.deploy(escrow.address); await governor.deployed(); console.log("VeloGovernor deployed to: ", governor.address); console.log("Args: ", escrow.address, "\n"); // Airdrop - const claim = await MerkleClaim.deploy(velo.address, OP_CONFIG.merkleRoot); - await claim.deployed(); - console.log("MerkleClaim deployed to: ", claim.address); - console.log("Args: ", velo.address, OP_CONFIG.merkleRoot, "\n"); - // Initialize await velo.initialMint(OP_CONFIG.teamEOA); console.log("Initial minted"); - await velo.setRedemptionReceiver(receiver.address); - console.log("RedemptionReceiver set"); - - await velo.setMerkleClaim(claim.address); - console.log("MerkleClaim set"); - await velo.setMinter(minter.address); console.log("Minter set"); diff --git a/test/BaseTest.sol b/test/BaseTest.sol index edd1a61b..e074afb0 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -7,9 +7,6 @@ import "contracts/factories/BribeFactory.sol"; import "contracts/factories/GaugeFactory.sol"; import "contracts/factories/PairFactory.sol"; import "contracts/factories/WrappedExternalBribeFactory.sol"; -import "contracts/redeem/MerkleClaim.sol"; -import "contracts/redeem/RedemptionReceiver.sol"; -import "contracts/redeem/RedemptionSender.sol"; import "contracts/InternalBribe.sol"; import "contracts/ExternalBribe.sol"; import "contracts/Gauge.sol"; diff --git a/test/Redeem.t.sol b/test/Redeem.t.sol deleted file mode 100644 index 58a097ba..00000000 --- a/test/Redeem.t.sol +++ /dev/null @@ -1,117 +0,0 @@ -pragma solidity 0.8.13; - -import "./BaseTest.sol"; -import "utils/TestEndpoint.sol"; - -contract RedeemTest is BaseTest { - TestEndpoint endpoint; - RedemptionSender sender; - RedemptionReceiver receiver; - MerkleClaim claim; - - uint256 public constant redeemableUSDC = 10e6 * 1e6; - uint256 public constant redeemableVELO = 10e6 * 1e18; - - function setUp() public { - deployOwners(); - deployCoins(); - mintStables(); - - endpoint = new TestEndpoint(12); // mock LZ endpoint sending from Fantom - receiver = new RedemptionReceiver( - address(USDC), - address(VELO), - 12, - address(endpoint) - ); - sender = new RedemptionSender( - address(WEVE), - 11, - address(endpoint), - address(receiver) - ); - - USDC.mint(address(this), redeemableUSDC); - USDC.approve(address(receiver), redeemableUSDC); - - VELO.setRedemptionReceiver(address(receiver)); - receiver.initializeReceiverWith( - address(sender), - redeemableUSDC, - redeemableVELO - ); - - claim = new MerkleClaim( - address(VELO), - 0xd0aa6a4e5b4e13462921d7518eebdb7b297a7877d6cfe078b0c318827392fb55 - ); // root that mints User 100e18 tokens - VELO.setMerkleClaim(address(claim)); - } - - function testRedemption(address redeemer, uint128 amount) public { - vm.assume(redeemer != address(0) && redeemer != address(owner) && 1 < amount && amount < sender.ELIGIBLE_WEVE()); - - uint256 beforeUSDC = USDC.balanceOf(redeemer); - - WEVE.mint(redeemer, amount); - vm.startPrank(redeemer); - WEVE.approve(address(sender), amount); - sender.redeemWEVE(amount / 2, address(0), bytes("")); - sender.redeemWEVE(amount / 2, address(0), bytes("")); - vm.stopPrank(); - - assertApproxEqAbs( - USDC.balanceOf(redeemer) - beforeUSDC, - (amount * redeemableUSDC) / sender.ELIGIBLE_WEVE(), - 1 - ); - - // check that team can't claim - vm.expectRevert(abi.encodePacked("LEFTOVERS_NOT_CLAIMABLE")); - receiver.claimLeftovers(); - - // fwd 1 month - vm.warp(block.timestamp + 30 days); - - // check that not anyone can claim - vm.startPrank(address(receiver)); - vm.expectRevert(abi.encodePacked("ONLY_TEAM")); - receiver.claimLeftovers(); - vm.stopPrank(); - - // check that team can claim - assertGt(USDC.balanceOf(address(receiver)), 0); - - receiver.claimLeftovers(); - - assertEq(USDC.balanceOf(address(receiver)), 0); - } - - function testClaimAirdrop() public { - address user = 0x185a4dc360CE69bDCceE33b3784B0282f7961aea; - - // Setup correct proof - bytes32[] memory proof = new bytes32[](1); - proof[0] = 0xceeae64152a2deaf8c661fccd5645458ba20261b16d2f6e090fe908b0ac9ca88; - - // Collect balance of tokens before claim - uint256 preBalance = VELO.balanceOf(user); - - // Claim tokens - vm.startPrank(user); - claim.claim( - // Claiming for user - user, - // 100 tokens - 100e18, - // With valid proof - proof - ); - - // Collect balance of tokens after claim - uint256 postBalance = VELO.balanceOf(user); - - // Assert balance before + 100 tokens = after balance - assertEq(postBalance, preBalance + 100e18); - } -} diff --git a/test/utils/TestEndpoint.sol b/test/utils/TestEndpoint.sol deleted file mode 100644 index 9b614bd4..00000000 --- a/test/utils/TestEndpoint.sol +++ /dev/null @@ -1,45 +0,0 @@ -pragma solidity 0.8.13; - -import "LayerZero/interfaces/ILayerZeroReceiver.sol"; -import "contracts/redeem/RedemptionReceiver.sol"; - -contract TestEndpoint { - RedemptionReceiver receiver; - uint16 public immutable chainId; - uint64 public nonce; - - constructor(uint16 _chainId) { - chainId = _chainId; - } - - function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64) { - return 0; - } - - function send( - uint16, - bytes calldata destination, - bytes calldata payload, - address payable, - address, - bytes calldata - ) external payable { - ILayerZeroReceiver(addressFromPackedBytes(destination)).lzReceive( - chainId, - abi.encodePacked(msg.sender), - nonce++, - payload - ); - } - - function addressFromPackedBytes(bytes memory toAddressBytes) - public - pure - returns (address toAddress) - { - // solhint-disable-next-line no-inline-assembly - assembly { - toAddress := mload(add(toAddressBytes, 20)) - } - } -} diff --git a/test/utils/TestOwner.sol b/test/utils/TestOwner.sol index b283fafc..bad07794 100644 --- a/test/utils/TestOwner.sol +++ b/test/utils/TestOwner.sol @@ -1,7 +1,6 @@ pragma solidity 0.8.13; import "solmate/test/utils/mocks/MockERC20.sol"; -import "contracts/redeem/RedemptionSender.sol"; import "contracts/Gauge.sol"; import "contracts/Minter.sol"; import "contracts/Pair.sol"; @@ -24,14 +23,6 @@ contract TestOwner { MockERC20(_token).transfer(_to, _amount); } - /*////////////////////////////////////////////////////////////// - RedemptionSender - //////////////////////////////////////////////////////////////*/ - - function redeemWEVE(address _sender, uint256 _amount) public { - RedemptionSender(_sender).redeemWEVE(_amount, address(0), bytes('')); - } - /*////////////////////////////////////////////////////////////// Pair //////////////////////////////////////////////////////////////*/ From 411f88fa939be4eb9684f468ce5440df9af5cb9f Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:19:42 +0000 Subject: [PATCH 035/156] forge install: forge-std v1.5.0 --- .gitmodules | 1 + lib/forge-std | 1 + 2 files changed, 2 insertions(+) create mode 160000 lib/forge-std diff --git a/.gitmodules b/.gitmodules index f9f7c92c..9c5278d6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,7 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std + branch = v1.5.0 [submodule "lib/solmate"] path = lib/solmate url = https://github.com/Rari-Capital/solmate diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 00000000..c2236853 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit c2236853aadb8e2d9909bbecdc490099519b70a4 From 24e13a437dccb31965b7699b07c1497962dd914d Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:20:24 +0000 Subject: [PATCH 036/156] forge install: solmate --- .gitmodules | 2 +- lib/solmate | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 lib/solmate diff --git a/.gitmodules b/.gitmodules index 9c5278d6..2f17eb4d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,7 +7,7 @@ branch = v1.5.0 [submodule "lib/solmate"] path = lib/solmate - url = https://github.com/Rari-Capital/solmate + url = https://github.com/transmissions11/solmate [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/Openzeppelin/openzeppelin-contracts diff --git a/lib/solmate b/lib/solmate new file mode 160000 index 00000000..1b3adf67 --- /dev/null +++ b/lib/solmate @@ -0,0 +1 @@ +Subproject commit 1b3adf677e7e383cc684b5d5bd441da86bf4bf1c From 808bd90544058f06acafdf7c63e476abc8351410 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:26:53 +0000 Subject: [PATCH 037/156] build: Remove L0 from gitmodules --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2f17eb4d..6a0cc9f6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,6 +12,3 @@ path = lib/openzeppelin-contracts url = https://github.com/Openzeppelin/openzeppelin-contracts branch = v4.8.2 -[submodule "lib/LayerZero"] - path = lib/LayerZero - url = https://github.com/LayerZero-Labs/LayerZero From af760d027dbcc14c65d6b2bb7f7af5db9829cf83 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:37:59 +0000 Subject: [PATCH 038/156] fix: Gauge reward token precision based on ERC20 token decimals --- contracts/Gauge.sol | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/contracts/Gauge.sol b/contracts/Gauge.sol index 65325999..e0eb5566 100644 --- a/contracts/Gauge.sol +++ b/contracts/Gauge.sol @@ -24,7 +24,6 @@ contract Gauge is IGauge { bool public isForPair; uint internal constant DURATION = 7 days; // rewards are released over 7 days - uint internal constant PRECISION = 10 ** 18; uint internal constant MAX_REWARD_TOKENS = 16; // default snx staking contract implementation @@ -287,7 +286,7 @@ contract Gauge is IGauge { if (derivedSupply == 0) { return rewardPerTokenStored[token]; } - return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * PRECISION / derivedSupply); + return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * (10**IERC20(token).decimals()) / derivedSupply); } function derivedBalance(address account) public view returns (uint) { @@ -329,7 +328,7 @@ contract Gauge is IGauge { function _calcRewardPerToken(address token, uint timestamp1, uint timestamp0, uint supply, uint startTimestamp) internal view returns (uint, uint) { uint endTime = Math.max(timestamp1, startTimestamp); - return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * PRECISION / supply), endTime); + return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * (10**IERC20(token).decimals()) / supply), endTime); } /// @dev Update stored rewardPerToken values without the last one snapshot @@ -406,13 +405,13 @@ contract Gauge is IGauge { Checkpoint memory cp1 = checkpoints[account][i+1]; (uint _rewardPerTokenStored0,) = getPriorRewardPerToken(token, cp0.timestamp); (uint _rewardPerTokenStored1,) = getPriorRewardPerToken(token, cp1.timestamp); - reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / PRECISION; + reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / (10**IERC20(token).decimals()); } } Checkpoint memory cp = checkpoints[account][_endIndex]; (uint _rewardPerTokenStored,) = getPriorRewardPerToken(token, cp.timestamp); - reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][account])) / PRECISION; + reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][account])) / (10**IERC20(token).decimals()); return reward; } From 1ccb1b8b70452d5a56382877c2965e77a5b84320 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:41:11 +0000 Subject: [PATCH 039/156] feat: Allow pair fee to be 0 --- contracts/Pair.sol | 28 ++++++++++++++++------------ contracts/factories/PairFactory.sol | 1 - 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 78901497..ff71ae0c 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -149,23 +149,27 @@ contract Pair is IPair { // Accrue fees on token0. function _update0(uint amount) internal { - if (!hasGauge) { - _safeTransfer(token0, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - emit TankFees(token0, amount, tank); - } else { - IBribe(externalBribe).notifyRewardAmount(token0, amount); //transfer fees to exBribes - emit GaugeFees(token0, amount, externalBribe); + if (amount != 0) { + if (hasGauge) { + IBribe(externalBribe).notifyRewardAmount(token0, amount); // transfer fees to exBribes + emit GaugeFees(token0, amount, externalBribe); + } else { + _safeTransfer(token0, tank, amount); // transfer the fees to tank MSig for gaugeless LPs + emit TankFees(token0, amount, tank); + } } } // Accrue fees on token1 function _update1(uint amount) internal { - if (!hasGauge) { - _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - emit TankFees(token1, amount, tank); - } else { - IBribe(externalBribe).notifyRewardAmount(token1, amount); //transfer fees to exBribes - emit GaugeFees(token1, amount, externalBribe); + if (amount != 0) { + if (hasGauge) { + IBribe(externalBribe).notifyRewardAmount(token1, amount); // transfer fees to exBribes + emit GaugeFees(token1, amount, externalBribe); + } else { + _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs + emit TankFees(token1, amount, tank); + } } } diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 5b77d9a6..06b12892 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -108,7 +108,6 @@ contract PairFactory is IPairFactory { function setFee(bool _stable, uint256 _fee) external { require(msg.sender == feeManager, 'not fee manager'); require(_fee <= MAX_FEE, 'fee too high'); - require(_fee != 0, 'fee must be nonzero'); if (_stable) { stableFee = _fee; } else { From 3ab00b0556f92d9af265bb01628d9843bed52be7 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:50:15 +0000 Subject: [PATCH 040/156] chore: Remove internal bribe --- contracts/Gauge.sol | 4 +- contracts/InternalBribe.sol | 477 ------------------------- contracts/Voter.sol | 11 +- contracts/factories/BribeFactory.sol | 7 - contracts/factories/GaugeFactory.sol | 4 +- contracts/interfaces/IBribeFactory.sol | 1 - test/BaseTest.sol | 1 - test/ExternalBribes.t.sol | 2 - test/Imbalance.t.sol | 1 - test/KillGauges.t.sol | 8 - test/Pair.t.sol | 9 - test/VeloGovernor.t.sol | 3 - test/WashTrade.t.sol | 53 --- test/WrappedExternalBribes.t.sol | 2 - 14 files changed, 6 insertions(+), 577 deletions(-) delete mode 100644 contracts/InternalBribe.sol diff --git a/contracts/Gauge.sol b/contracts/Gauge.sol index e0eb5566..424f2461 100644 --- a/contracts/Gauge.sol +++ b/contracts/Gauge.sol @@ -14,7 +14,6 @@ contract Gauge is IGauge { address public immutable stake; // the LP token that needs to be staked for rewards address public immutable _ve; // the ve token used for gauges - address public immutable internal_bribe; address public immutable external_bribe; address public immutable voter; @@ -82,9 +81,8 @@ contract Gauge is IGauge { event NotifyReward(address indexed from, address indexed reward, uint amount); event ClaimRewards(address indexed from, address indexed reward, uint amount); - constructor(address _stake, address _internal_bribe, address _external_bribe, address __ve, address _voter, bool _forPair, address[] memory _allowedRewardTokens) { + constructor(address _stake, address _external_bribe, address __ve, address _voter, bool _forPair, address[] memory _allowedRewardTokens) { stake = _stake; - internal_bribe = _internal_bribe; external_bribe = _external_bribe; _ve = __ve; voter = _voter; diff --git a/contracts/InternalBribe.sol b/contracts/InternalBribe.sol deleted file mode 100644 index ac00876c..00000000 --- a/contracts/InternalBribe.sol +++ /dev/null @@ -1,477 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; -import 'contracts/interfaces/IBribe.sol'; -import 'contracts/interfaces/IERC20.sol'; -import 'contracts/interfaces/IVoter.sol'; -import 'contracts/interfaces/IVotingEscrow.sol'; - -// Bribes pay out rewards for a given pool based on the votes that were received from the user (goes hand in hand with Voter.vote()) -contract InternalBribe is IBribe { - - address public immutable voter; // only voter can modify balances (since it only happens on vote()) - address public immutable _ve; - - uint public constant DURATION = 7 days; // rewards are released over 7 days - uint internal constant MAX_REWARD_TOKENS = 16; - - // default snx staking contract implementation - mapping(address => uint) public rewardRate; - mapping(address => uint) public periodFinish; - mapping(address => uint) public lastUpdateTime; - mapping(address => uint) public rewardPerTokenStored; - - mapping(address => mapping(uint => uint)) public lastEarn; - mapping(address => mapping(uint => uint)) public userRewardPerTokenStored; - - address[] public rewards; - mapping(address => bool) public isReward; - - uint public totalSupply; - mapping(uint => uint) public balanceOf; - - /// @notice A checkpoint for marking balance - struct Checkpoint { - uint timestamp; - uint balanceOf; - } - - /// @notice A checkpoint for marking reward rate - struct RewardPerTokenCheckpoint { - uint timestamp; - uint rewardPerToken; - } - - /// @notice A checkpoint for marking supply - struct SupplyCheckpoint { - uint timestamp; - uint supply; - } - - /// @notice A record of balance checkpoints for each account, by index - mapping (uint => mapping (uint => Checkpoint)) public checkpoints; - /// @notice The number of checkpoints for each account - mapping (uint => uint) public numCheckpoints; - /// @notice A record of balance checkpoints for each token, by index - mapping (uint => SupplyCheckpoint) public supplyCheckpoints; - /// @notice The number of checkpoints - uint public supplyNumCheckpoints; - /// @notice A record of balance checkpoints for each token, by index - mapping (address => mapping (uint => RewardPerTokenCheckpoint)) public rewardPerTokenCheckpoints; - /// @notice The number of checkpoints for each token - mapping (address => uint) public rewardPerTokenNumCheckpoints; - - event Deposit(address indexed from, uint tokenId, uint amount); - event Withdraw(address indexed from, uint tokenId, uint amount); - event NotifyReward(address indexed from, address indexed reward, uint amount); - event ClaimRewards(address indexed from, address indexed reward, uint amount); - - constructor(address _voter, address[] memory _allowedRewardTokens) { - voter = _voter; - _ve = IVoter(_voter)._ve(); - - for (uint i; i < _allowedRewardTokens.length; i++) { - if (_allowedRewardTokens[i] != address(0)) { - isReward[_allowedRewardTokens[i]] = true; - rewards.push(_allowedRewardTokens[i]); - } - } - } - - // simple re-entrancy check - uint internal _unlocked = 1; - modifier lock() { - require(_unlocked == 1); - _unlocked = 2; - _; - _unlocked = 1; - } - - /** - * @notice Determine the prior balance for an account as of a block number - * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. - * @param tokenId The token of the NFT to check - * @param timestamp The timestamp to get the balance at - * @return The balance the account had as of the given block - */ - function getPriorBalanceIndex(uint tokenId, uint timestamp) public view returns (uint) { - uint nCheckpoints = numCheckpoints[tokenId]; - if (nCheckpoints == 0) { - return 0; - } - - // First check most recent balance - if (checkpoints[tokenId][nCheckpoints - 1].timestamp <= timestamp) { - return (nCheckpoints - 1); - } - - // Next check implicit zero balance - if (checkpoints[tokenId][0].timestamp > timestamp) { - return 0; - } - - uint lower = 0; - uint upper = nCheckpoints - 1; - while (upper > lower) { - uint center = upper - (upper - lower) / 2; // ceil, avoiding overflow - Checkpoint memory cp = checkpoints[tokenId][center]; - if (cp.timestamp == timestamp) { - return center; - } else if (cp.timestamp < timestamp) { - lower = center; - } else { - upper = center - 1; - } - } - return lower; - } - - function getPriorSupplyIndex(uint timestamp) public view returns (uint) { - uint nCheckpoints = supplyNumCheckpoints; - if (nCheckpoints == 0) { - return 0; - } - - // First check most recent balance - if (supplyCheckpoints[nCheckpoints - 1].timestamp <= timestamp) { - return (nCheckpoints - 1); - } - - // Next check implicit zero balance - if (supplyCheckpoints[0].timestamp > timestamp) { - return 0; - } - - uint lower = 0; - uint upper = nCheckpoints - 1; - while (upper > lower) { - uint center = upper - (upper - lower) / 2; // ceil, avoiding overflow - SupplyCheckpoint memory cp = supplyCheckpoints[center]; - if (cp.timestamp == timestamp) { - return center; - } else if (cp.timestamp < timestamp) { - lower = center; - } else { - upper = center - 1; - } - } - return lower; - } - - function getPriorRewardPerToken(address token, uint timestamp) public view returns (uint, uint) { - uint nCheckpoints = rewardPerTokenNumCheckpoints[token]; - if (nCheckpoints == 0) { - return (0,0); - } - - // First check most recent balance - if (rewardPerTokenCheckpoints[token][nCheckpoints - 1].timestamp <= timestamp) { - return (rewardPerTokenCheckpoints[token][nCheckpoints - 1].rewardPerToken, rewardPerTokenCheckpoints[token][nCheckpoints - 1].timestamp); - } - - // Next check implicit zero balance - if (rewardPerTokenCheckpoints[token][0].timestamp > timestamp) { - return (0,0); - } - - uint lower = 0; - uint upper = nCheckpoints - 1; - while (upper > lower) { - uint center = upper - (upper - lower) / 2; // ceil, avoiding overflow - RewardPerTokenCheckpoint memory cp = rewardPerTokenCheckpoints[token][center]; - if (cp.timestamp == timestamp) { - return (cp.rewardPerToken, cp.timestamp); - } else if (cp.timestamp < timestamp) { - lower = center; - } else { - upper = center - 1; - } - } - return (rewardPerTokenCheckpoints[token][lower].rewardPerToken, rewardPerTokenCheckpoints[token][lower].timestamp); - } - - function _writeCheckpoint(uint tokenId, uint balance) internal { - uint _timestamp = block.timestamp; - uint _nCheckPoints = numCheckpoints[tokenId]; - - if (_nCheckPoints > 0 && checkpoints[tokenId][_nCheckPoints - 1].timestamp == _timestamp) { - checkpoints[tokenId][_nCheckPoints - 1].balanceOf = balance; - } else { - checkpoints[tokenId][_nCheckPoints] = Checkpoint(_timestamp, balance); - numCheckpoints[tokenId] = _nCheckPoints + 1; - } - } - - function _writeRewardPerTokenCheckpoint(address token, uint reward, uint timestamp) internal { - uint _nCheckPoints = rewardPerTokenNumCheckpoints[token]; - - if (_nCheckPoints > 0 && rewardPerTokenCheckpoints[token][_nCheckPoints - 1].timestamp == timestamp) { - rewardPerTokenCheckpoints[token][_nCheckPoints - 1].rewardPerToken = reward; - } else { - rewardPerTokenCheckpoints[token][_nCheckPoints] = RewardPerTokenCheckpoint(timestamp, reward); - rewardPerTokenNumCheckpoints[token] = _nCheckPoints + 1; - } - } - - function _writeSupplyCheckpoint() internal { - uint _nCheckPoints = supplyNumCheckpoints; - uint _timestamp = block.timestamp; - - if (_nCheckPoints > 0 && supplyCheckpoints[_nCheckPoints - 1].timestamp == _timestamp) { - supplyCheckpoints[_nCheckPoints - 1].supply = totalSupply; - } else { - supplyCheckpoints[_nCheckPoints] = SupplyCheckpoint(_timestamp, totalSupply); - supplyNumCheckpoints = _nCheckPoints + 1; - } - } - - function rewardsListLength() external view returns (uint) { - return rewards.length; - } - - // returns the last time the reward was modified or periodFinish if the reward has ended - function lastTimeRewardApplicable(address token) public view returns (uint) { - return Math.min(block.timestamp, periodFinish[token]); - } - - // allows a user to claim rewards for a given token - function getReward(uint tokenId, address[] memory tokens) external lock { - require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, tokenId)); - for (uint i = 0; i < tokens.length; i++) { - (rewardPerTokenStored[tokens[i]], lastUpdateTime[tokens[i]]) = _updateRewardPerToken(tokens[i], type(uint).max, true); - - uint _reward = earned(tokens[i], tokenId); - lastEarn[tokens[i]][tokenId] = block.timestamp; - userRewardPerTokenStored[tokens[i]][tokenId] = rewardPerTokenStored[tokens[i]]; - if (_reward > 0) _safeTransfer(tokens[i], msg.sender, _reward); - - emit ClaimRewards(msg.sender, tokens[i], _reward); - } - } - - // used by Voter to allow batched reward claims - function getRewardForOwner(uint tokenId, address[] memory tokens) external lock { - require(msg.sender == voter); - address _owner = IVotingEscrow(_ve).ownerOf(tokenId); - for (uint i = 0; i < tokens.length; i++) { - (rewardPerTokenStored[tokens[i]], lastUpdateTime[tokens[i]]) = _updateRewardPerToken(tokens[i], type(uint).max, true); - - uint _reward = earned(tokens[i], tokenId); - lastEarn[tokens[i]][tokenId] = block.timestamp; - userRewardPerTokenStored[tokens[i]][tokenId] = rewardPerTokenStored[tokens[i]]; - if (_reward > 0) _safeTransfer(tokens[i], _owner, _reward); - - emit ClaimRewards(_owner, tokens[i], _reward); - } - } - - function rewardPerToken(address token) public view returns (uint) { - if (totalSupply == 0) { - return rewardPerTokenStored[token]; - } - return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * 10**IERC20(token).decimals() / totalSupply); - } - - function batchRewardPerToken(address token, uint maxRuns) external { - (rewardPerTokenStored[token], lastUpdateTime[token]) = _batchRewardPerToken(token, maxRuns); - } - - function _batchRewardPerToken(address token, uint maxRuns) internal returns (uint, uint) { - uint _startTimestamp = lastUpdateTime[token]; - uint reward = rewardPerTokenStored[token]; - - if (supplyNumCheckpoints == 0) { - return (reward, _startTimestamp); - } - - if (rewardRate[token] == 0) { - return (reward, block.timestamp); - } - - uint _startIndex = getPriorSupplyIndex(_startTimestamp); - uint _endIndex = Math.min(supplyNumCheckpoints-1, maxRuns); - - for (uint i = _startIndex; i < _endIndex; i++) { - SupplyCheckpoint memory sp0 = supplyCheckpoints[i]; - if (sp0.supply > 0) { - SupplyCheckpoint memory sp1 = supplyCheckpoints[i+1]; - (uint _reward, uint endTime) = _calcRewardPerToken(token, sp1.timestamp, sp0.timestamp, sp0.supply, _startTimestamp); - reward += _reward; - _writeRewardPerTokenCheckpoint(token, reward, endTime); - _startTimestamp = endTime; - } - } - - return (reward, _startTimestamp); - } - - function _calcRewardPerToken(address token, uint timestamp1, uint timestamp0, uint supply, uint startTimestamp) internal view returns (uint, uint) { - uint endTime = Math.max(timestamp1, startTimestamp); - return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * 10**IERC20(token).decimals() / supply), endTime); - } - - /// @dev Update stored rewardPerToken values without the last one snapshot - /// If the contract will get "out of gas" error on users actions this will be helpful - function batchUpdateRewardPerToken(address token, uint maxRuns) external { - (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, maxRuns, false); - } - - function _updateRewardForAllTokens() internal { - uint length = rewards.length; - for (uint i; i < length; i++) { - address token = rewards[i]; - (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, type(uint).max, true); - } - } - - function _updateRewardPerToken(address token, uint maxRuns, bool actualLast) internal returns (uint, uint) { - uint _startTimestamp = lastUpdateTime[token]; - uint reward = rewardPerTokenStored[token]; - - if (supplyNumCheckpoints == 0) { - return (reward, _startTimestamp); - } - - if (rewardRate[token] == 0) { - return (reward, block.timestamp); - } - - uint _startIndex = getPriorSupplyIndex(_startTimestamp); - uint _endIndex = Math.min(supplyNumCheckpoints - 1, maxRuns); - - if (_endIndex > 0) { - for (uint i = _startIndex; i <= _endIndex - 1; i++) { - SupplyCheckpoint memory sp0 = supplyCheckpoints[i]; - if (sp0.supply > 0) { - SupplyCheckpoint memory sp1 = supplyCheckpoints[i+1]; - (uint _reward, uint _endTime) = _calcRewardPerToken(token, sp1.timestamp, sp0.timestamp, sp0.supply, _startTimestamp); - reward += _reward; - _writeRewardPerTokenCheckpoint(token, reward, _endTime); - _startTimestamp = _endTime; - } - } - } - - if (actualLast) { - SupplyCheckpoint memory sp = supplyCheckpoints[_endIndex]; - if (sp.supply > 0) { - (uint _reward,) = _calcRewardPerToken(token, lastTimeRewardApplicable(token), Math.max(sp.timestamp, _startTimestamp), sp.supply, _startTimestamp); - reward += _reward; - _writeRewardPerTokenCheckpoint(token, reward, block.timestamp); - _startTimestamp = block.timestamp; - } - } - - return (reward, _startTimestamp); - } - - function earned(address token, uint tokenId) public view returns (uint) { - uint _startTimestamp = Math.max(lastEarn[token][tokenId], rewardPerTokenCheckpoints[token][0].timestamp); - if (numCheckpoints[tokenId] == 0) { - return 0; - } - - uint _startIndex = getPriorBalanceIndex(tokenId, _startTimestamp); - uint _endIndex = numCheckpoints[tokenId]-1; - - uint reward = 0; - - if (_endIndex > 0) { - for (uint i = _startIndex; i <= _endIndex-1; i++) { - Checkpoint memory cp0 = checkpoints[tokenId][i]; - Checkpoint memory cp1 = checkpoints[tokenId][i+1]; - (uint _rewardPerTokenStored0,) = getPriorRewardPerToken(token, cp0.timestamp); - (uint _rewardPerTokenStored1,) = getPriorRewardPerToken(token, cp1.timestamp); - reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / 10**IERC20(token).decimals(); - } - } - - Checkpoint memory cp = checkpoints[tokenId][_endIndex]; - (uint _rewardPerTokenStored,) = getPriorRewardPerToken(token, cp.timestamp); - reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][tokenId])) / 10**IERC20(token).decimals(); - - return reward; - } - - // This is an external function, but internal notation is used since it can only be called "internally" from Gauges - function _deposit(uint amount, uint tokenId) external { - require(msg.sender == voter); - _updateRewardForAllTokens(); - - totalSupply += amount; - balanceOf[tokenId] += amount; - - _writeCheckpoint(tokenId, balanceOf[tokenId]); - _writeSupplyCheckpoint(); - - emit Deposit(msg.sender, tokenId, amount); - } - - function _withdraw(uint amount, uint tokenId) external { - require(msg.sender == voter); - _updateRewardForAllTokens(); - - totalSupply -= amount; - balanceOf[tokenId] -= amount; - - _writeCheckpoint(tokenId, balanceOf[tokenId]); - _writeSupplyCheckpoint(); - - emit Withdraw(msg.sender, tokenId, amount); - } - - function left(address token) external view returns (uint) { - if (block.timestamp >= periodFinish[token]) return 0; - uint _remaining = periodFinish[token] - block.timestamp; - return _remaining * rewardRate[token]; - } - - // used to notify a gauge/bribe of a given reward, this can create griefing attacks by extending rewards - function notifyRewardAmount(address token, uint amount) external lock { - require(amount > 0); - require(isReward[token]); - - if (rewardRate[token] == 0) _writeRewardPerTokenCheckpoint(token, 0, block.timestamp); - (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, type(uint).max, true); - - if (block.timestamp >= periodFinish[token]) { - _safeTransferFrom(token, msg.sender, address(this), amount); - rewardRate[token] = amount / DURATION; - } else { - uint _remaining = periodFinish[token] - block.timestamp; - uint _left = _remaining * rewardRate[token]; - require(amount > _left); - _safeTransferFrom(token, msg.sender, address(this), amount); - rewardRate[token] = (amount + _left) / DURATION; - } - require(rewardRate[token] > 0); - uint balance = IERC20(token).balanceOf(address(this)); - require(rewardRate[token] <= balance / DURATION, "Provided reward too high"); - periodFinish[token] = block.timestamp + DURATION; - - emit NotifyReward(msg.sender, token, amount); - } - - function swapOutRewardToken(uint i, address oldToken, address newToken) external { - require(msg.sender == IVotingEscrow(_ve).team(), 'only team'); - require(rewards[i] == oldToken); - isReward[oldToken] = false; - isReward[newToken] = true; - rewards[i] = newToken; - } - - function _safeTransfer(address token, address to, uint256 value) internal { - require(token.code.length > 0); - (bool success, bytes memory data) = - token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool)))); - } - - function _safeTransferFrom(address token, address from, address to, uint256 value) internal { - require(token.code.length > 0); - (bool success, bytes memory data) = - token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); - require(success && (data.length == 0 || abi.decode(data, (bool)))); - } -} diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 9ff7ab20..7716e2a3 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -33,7 +33,6 @@ contract Voter is IVoter { address[] public pools; // all pools viable for incentives mapping(address => address) public gauges; // pool => gauge mapping(address => address) public poolForGauge; // gauge => pool - mapping(address => address) public internal_bribes; // gauge => internal bribe (only fees) mapping(address => address) public external_bribes; // gauge => external bribe (real bribes) mapping(address => uint256) public weights; // pool => weight mapping(uint => mapping(address => uint256)) public votes; // nft => pool => votes @@ -44,7 +43,7 @@ contract Voter is IVoter { mapping(address => bool) public isWhitelisted; mapping(address => bool) public isAlive; - event GaugeCreated(address indexed gauge, address creator, address internal_bribe, address indexed external_bribe, address wxbribe, address indexed pool); + event GaugeCreated(address indexed gauge, address creator, address indexed external_bribe, address wxbribe, address indexed pool); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted(address indexed voter, uint tokenId, uint256 weight); @@ -124,7 +123,6 @@ contract Voter is IVoter { weights[_pool] -= _votes; votes[_tokenId][_pool] -= _votes; if (_votes > 0) { - IBribe(internal_bribes[gauges[_pool]])._withdraw(uint256(_votes), _tokenId); IBribe(external_bribes[gauges[_pool]])._withdraw(uint256(_votes), _tokenId); _totalWeight += _votes; } else { @@ -177,7 +175,6 @@ contract Voter is IVoter { weights[_pool] += _poolWeight; votes[_tokenId][_pool] += _poolWeight; - IBribe(internal_bribes[_gauge])._deposit(uint256(_poolWeight), _tokenId); IBribe(external_bribes[_gauge])._deposit(uint256(_poolWeight), _tokenId); _usedWeight += _poolWeight; _totalWeight += _poolWeight; @@ -232,13 +229,11 @@ contract Voter is IVoter { require(isWhitelisted[tokenA] && isWhitelisted[tokenB], "!whitelisted"); } - address _internal_bribe = IBribeFactory(bribefactory).createInternalBribe(internalRewards); address _external_bribe = IBribeFactory(bribefactory).createExternalBribe(allowedRewards); address _wxbribe = IWrappedExternalBribeFactory(wrappedExternalBribeFactory).createBribe(_external_bribe); - address _gauge = IGaugeFactory(gaugefactory).createGauge(_pool, _internal_bribe, _external_bribe, _ve, isPair, allowedRewards); + address _gauge = IGaugeFactory(gaugefactory).createGauge(_pool, _external_bribe, _ve, isPair, allowedRewards); IERC20(base).approve(_gauge, type(uint).max); - internal_bribes[_gauge] = _internal_bribe; external_bribes[_gauge] = _external_bribe; gauges[_pool] = _gauge; poolForGauge[_gauge] = _pool; @@ -248,7 +243,7 @@ contract Voter is IVoter { pools.push(_pool); IPair(_pool).setHasGauge(true); IPair(_pool).setExternalBribe(_wxbribe); - emit GaugeCreated(_gauge, msg.sender, _internal_bribe, _external_bribe, _wxbribe, _pool); + emit GaugeCreated(_gauge, msg.sender, _external_bribe, _wxbribe, _pool); return _gauge; } diff --git a/contracts/factories/BribeFactory.sol b/contracts/factories/BribeFactory.sol index fda59613..b945c859 100644 --- a/contracts/factories/BribeFactory.sol +++ b/contracts/factories/BribeFactory.sol @@ -2,18 +2,11 @@ pragma solidity 0.8.13; import "contracts/interfaces/IBribeFactory.sol"; -import 'contracts/InternalBribe.sol'; import 'contracts/ExternalBribe.sol'; contract BribeFactory is IBribeFactory { - address public last_internal_bribe; address public last_external_bribe; - function createInternalBribe(address[] memory allowedRewards) external returns (address) { - last_internal_bribe = address(new InternalBribe(msg.sender, allowedRewards)); - return last_internal_bribe; - } - function createExternalBribe(address[] memory allowedRewards) external returns (address) { last_external_bribe = address(new ExternalBribe(msg.sender, allowedRewards)); return last_external_bribe; diff --git a/contracts/factories/GaugeFactory.sol b/contracts/factories/GaugeFactory.sol index dc37fd05..5e8ba6f0 100644 --- a/contracts/factories/GaugeFactory.sol +++ b/contracts/factories/GaugeFactory.sol @@ -7,8 +7,8 @@ import 'contracts/Gauge.sol'; contract GaugeFactory is IGaugeFactory { address public last_gauge; - function createGauge(address _pool, address _internal_bribe, address _external_bribe, address _ve, bool isPair, address[] memory allowedRewards) external returns (address) { - last_gauge = address(new Gauge(_pool, _internal_bribe, _external_bribe, _ve, msg.sender, isPair, allowedRewards)); + function createGauge(address _pool, address _external_bribe, address _ve, bool isPair, address[] memory allowedRewards) external returns (address) { + last_gauge = address(new Gauge(_pool, _external_bribe, _ve, msg.sender, isPair, allowedRewards)); return last_gauge; } } diff --git a/contracts/interfaces/IBribeFactory.sol b/contracts/interfaces/IBribeFactory.sol index d22e6465..8768989f 100644 --- a/contracts/interfaces/IBribeFactory.sol +++ b/contracts/interfaces/IBribeFactory.sol @@ -1,6 +1,5 @@ pragma solidity 0.8.13; interface IBribeFactory { - function createInternalBribe(address[] memory) external returns (address); function createExternalBribe(address[] memory) external returns (address); } diff --git a/test/BaseTest.sol b/test/BaseTest.sol index e074afb0..23dc0cf7 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -7,7 +7,6 @@ import "contracts/factories/BribeFactory.sol"; import "contracts/factories/GaugeFactory.sol"; import "contracts/factories/PairFactory.sol"; import "contracts/factories/WrappedExternalBribeFactory.sol"; -import "contracts/InternalBribe.sol"; import "contracts/ExternalBribe.sol"; import "contracts/Gauge.sol"; import "contracts/Minter.sol"; diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index 134949b3..2b04d780 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -11,7 +11,6 @@ contract ExternalBribesTest is BaseTest { RewardsDistributor distributor; Minter minter; Gauge gauge; - InternalBribe bribe; ExternalBribe xbribe; PairFactory pairFactory; @@ -61,7 +60,6 @@ contract ExternalBribesTest is BaseTest { // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); - bribe = InternalBribe(gauge.internal_bribe()); xbribe = ExternalBribe(gauge.external_bribe()); // ve diff --git a/test/Imbalance.t.sol b/test/Imbalance.t.sol index 71e05a49..f9c9cd12 100644 --- a/test/Imbalance.t.sol +++ b/test/Imbalance.t.sol @@ -10,7 +10,6 @@ contract ImbalanceTest is BaseTest { WrappedExternalBribeFactory wxbribeFactory; Voter voter; Gauge gauge; - InternalBribe bribe; function deployBaseCoins() public { deployOwners(); diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index 4ed56891..0108fe75 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -14,8 +14,6 @@ contract KillGaugesTest is BaseTest { TestStakingRewards staking2; Gauge gauge; Gauge gauge2; - InternalBribe bribe; - InternalBribe bribe2; function setUp() public { deployOwners(); @@ -71,16 +69,10 @@ contract KillGaugesTest is BaseTest { staking2 = new TestStakingRewards(address(pair2), address(VELO)); address gaugeAddress = voter.gauges(address(pair)); - address bribeAddress = voter.internal_bribes(gaugeAddress); - gauge = Gauge(gaugeAddress); - bribe = InternalBribe(bribeAddress); address gaugeAddress2 = voter.gauges(address(pair2)); - address bribeAddress2 = voter.internal_bribes(gaugeAddress2); - gauge2 = Gauge(gaugeAddress2); - bribe2 = InternalBribe(bribeAddress2); } function testEmergencyCouncilCanKillAndReviveGauges() public { diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 23529a5b..90893de9 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -15,10 +15,7 @@ contract PairTest is BaseTest { Gauge gauge; Gauge gauge2; Gauge gauge3; - InternalBribe bribe; ExternalBribe xbribe; - InternalBribe bribe2; - InternalBribe bribe3; function deployPairCoins() public { vm.warp(block.timestamp + 1 weeks); // put some initial time in @@ -287,23 +284,17 @@ contract PairTest is BaseTest { staking = new TestStakingRewards(address(pair), address(VELO)); address gaugeAddress = voter.gauges(address(pair)); - address bribeAddress = voter.internal_bribes(gaugeAddress); address xBribeAddress = voter.external_bribes(gaugeAddress); address gaugeAddress2 = voter.gauges(address(pair2)); - address bribeAddress2 = voter.internal_bribes(gaugeAddress2); address gaugeAddress3 = voter.gauges(address(pair3)); - address bribeAddress3 = voter.internal_bribes(gaugeAddress3); gauge = Gauge(gaugeAddress); gauge2 = Gauge(gaugeAddress2); gauge3 = Gauge(gaugeAddress3); - bribe = InternalBribe(bribeAddress); xbribe = ExternalBribe(xBribeAddress); - bribe2 = InternalBribe(bribeAddress2); - bribe3 = InternalBribe(bribeAddress3); pair.approve(address(gauge), PAIR_1); pair.approve(address(staking), PAIR_1); diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol index 0358b0fb..c056f114 100644 --- a/test/VeloGovernor.t.sol +++ b/test/VeloGovernor.t.sol @@ -12,7 +12,6 @@ contract VeloGovernorTest is BaseTest { RewardsDistributor distributor; Minter minter; Gauge gauge; - InternalBribe bribe; VeloGovernor governor; function setUp() public { @@ -66,9 +65,7 @@ contract VeloGovernorTest is BaseTest { VELO.approve(address(gaugeFactory), 15 * TOKEN_100K); voter.createGauge(address(pair)); address gaugeAddress = voter.gauges(address(pair)); - address bribeAddress = voter.internal_bribes(gaugeAddress); gauge = Gauge(gaugeAddress); - bribe = InternalBribe(bribeAddress); governor = new VeloGovernor(escrow); voter.setGovernor(address(governor)); diff --git a/test/WashTrade.t.sol b/test/WashTrade.t.sol index b00ac36b..bc026e78 100644 --- a/test/WashTrade.t.sol +++ b/test/WashTrade.t.sol @@ -10,7 +10,6 @@ contract WashTradeTest is BaseTest { WrappedExternalBribeFactory wxbribeFactory; Voter voter; Gauge gauge3; - InternalBribe bribe3; function deployBaseCoins() public { vm.warp(block.timestamp + 1 weeks); // put some initial time in @@ -108,11 +107,9 @@ contract WashTradeTest is BaseTest { assertFalse(voter.gauges(address(pair3)) == address(0)); address gaugeAddr3 = voter.gauges(address(pair3)); - address bribeAddr3 = voter.internal_bribes(gaugeAddr3); gauge3 = Gauge(gaugeAddr3); - bribe3 = InternalBribe(bribeAddr3); uint256 total = pair3.balanceOf(address(owner)); pair3.approve(address(gauge3), total); gauge3.deposit(total, 0); @@ -170,55 +167,5 @@ contract WashTradeTest is BaseTest { weights[1] = 5000; voter.vote(1, pairs, weights); assertFalse(voter.totalWeight() == 0); - assertFalse(bribe3.balanceOf(1) == 0); - } - - function bribeClaimRewards() public { - voterVoteAndBribeBalanceOf(); - - address[] memory tokens = new address[](2); - tokens[0] = address(FRAX); - tokens[1] = address(DAI); - bribe3.getReward(1, tokens); - vm.warp(block.timestamp + 691200); - vm.roll(block.number + 1); - bribe3.getReward(1, tokens); - } - - function distributeAndClaimFees() public { - bribeClaimRewards(); - - vm.warp(block.timestamp + 691200); - vm.roll(block.number + 1); - address[] memory tokens = new address[](2); - tokens[0] = address(FRAX); - tokens[1] = address(DAI); - bribe3.getReward(1, tokens); - - address[] memory gauges = new address[](1); - gauges[0] = address(gauge3); - } - - function testBribeClaimRewards() public { - distributeAndClaimFees(); - - console2.log(bribe3.earned(address(FRAX), 1)); - console2.log(FRAX.balanceOf(address(owner))); - console2.log(FRAX.balanceOf(address(bribe3))); - bribe3.batchRewardPerToken(address(FRAX), 200); - bribe3.batchRewardPerToken(address(DAI), 200); - address[] memory tokens = new address[](2); - tokens[0] = address(FRAX); - tokens[1] = address(DAI); - bribe3.getReward(1, tokens); - vm.warp(block.timestamp + 691200); - vm.roll(block.number + 1); - console2.log(bribe3.earned(address(FRAX), 1)); - console2.log(FRAX.balanceOf(address(owner))); - console2.log(FRAX.balanceOf(address(bribe3))); - bribe3.getReward(1, tokens); - console2.log(bribe3.earned(address(FRAX), 1)); - console2.log(FRAX.balanceOf(address(owner))); - console2.log(FRAX.balanceOf(address(bribe3))); } } diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index 1e15d242..69efadc0 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -13,7 +13,6 @@ contract WrappedExternalBribesTest is BaseTest { RewardsDistributor distributor; Minter minter; Gauge gauge; - InternalBribe bribe; ExternalBribe xbribe; WrappedExternalBribe wxbribe; @@ -63,7 +62,6 @@ contract WrappedExternalBribesTest is BaseTest { // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); - bribe = InternalBribe(gauge.internal_bribe()); xbribe = ExternalBribe(gauge.external_bribe()); wxbribe = WrappedExternalBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); From 05760652f59874ba200c5eeefded40223a43650e Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:52:00 +0000 Subject: [PATCH 041/156] chore: Remove L0 from gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5a6eae14..4e5a6c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -30,5 +30,4 @@ scripts/xbribes Flattened.sol lib/openzeppelin-contracts lib/forge-std -lib/LayerZero -lib/forge-std \ No newline at end of file +lib/forge-std From b405f1a097a092e4aa0425c1bb8bed89c943f5c1 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:56:15 +0000 Subject: [PATCH 042/156] test: MockERC20 no longer needs claimFees --- test/BaseTest.sol | 2 +- test/utils/TestToken.sol | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 23dc0cf7..a098075f 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -46,7 +46,7 @@ abstract contract BaseTest is Test, TestOwner { Velo VELO; MockERC20 WEVE; MockERC20 LR; // late reward - TestToken stake; // MockERC20 with claimFees() function that returns (0,0) + TestToken stake; PairFactory factory; Router router; VelodromeLibrary lib; diff --git a/test/utils/TestToken.sol b/test/utils/TestToken.sol index 17246b5b..c837ac43 100644 --- a/test/utils/TestToken.sol +++ b/test/utils/TestToken.sol @@ -80,10 +80,6 @@ contract TestToken { return balanceOf[account]; } - function claimFees() external pure returns (uint, uint) { - return (0,0); - } - function _mint(address _to, uint _amount) internal returns (bool) { balanceOf[_to] += _amount; totalSupply += _amount; From 8176b68c25f1185a3e0fc28b12ee8a881239de0e Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 22:59:27 +0000 Subject: [PATCH 043/156] refactor: Merge _update0 and _update1 --- contracts/Pair.sol | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index ff71ae0c..7f9e1ba4 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -147,28 +147,14 @@ contract Pair is IPair { return (token0, token1); } - // Accrue fees on token0. - function _update0(uint amount) internal { + function _sendTokenFees(address token, uint amount) internal { if (amount != 0) { if (hasGauge) { - IBribe(externalBribe).notifyRewardAmount(token0, amount); // transfer fees to exBribes - emit GaugeFees(token0, amount, externalBribe); + IBribe(externalBribe).notifyRewardAmount(token, amount); // transfer fees to exBribes + emit GaugeFees(token, amount, externalBribe); } else { - _safeTransfer(token0, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - emit TankFees(token0, amount, tank); - } - } - } - - // Accrue fees on token1 - function _update1(uint amount) internal { - if (amount != 0) { - if (hasGauge) { - IBribe(externalBribe).notifyRewardAmount(token1, amount); // transfer fees to exBribes - emit GaugeFees(token1, amount, externalBribe); - } else { - _safeTransfer(token1, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - emit TankFees(token1, amount, tank); + _safeTransfer(token, tank, amount); // transfer the fees to tank MSig for gaugeless LPs + emit TankFees(token, amount, tank); } } } @@ -335,8 +321,8 @@ contract Pair is IPair { require(amount0In > 0 || amount1In > 0, 'IIA'); // Pair: INSUFFICIENT_INPUT_AMOUNT { // scope for reserve{0,1}Adjusted, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); - if (amount0In > 0) _update0(amount0In * PairFactory(factory).getFee(stable) / 10000); // accrue fees for token0 and move them out of pool - if (amount1In > 0) _update1(amount1In * PairFactory(factory).getFee(stable) / 10000); // accrue fees for token1 and move them out of pool + if (amount0In > 0) _sendTokenFees(token0, amount0In * PairFactory(factory).getFee(stable) / 10000); + if (amount1In > 0) _sendTokenFees(token1, amount1In * PairFactory(factory).getFee(stable) / 10000); _balance0 = IERC20(_token0).balanceOf(address(this)); // since we removed tokens, we need to reconfirm balances, can also simply use previous balance - amountIn/ 10000, but doing balanceOf again as safety check _balance1 = IERC20(_token1).balanceOf(address(this)); // The curve, either x3y+y3x for stable pools, or x*y for volatile pools From f4123222d87fe33ced128896d1b78354bf70a2d1 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 23:02:29 +0000 Subject: [PATCH 044/156] build: Initial mint 300m --- contracts/Velo.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/Velo.sol b/contracts/Velo.sol index 07b6abed..19b7a4ca 100644 --- a/contracts/Velo.sol +++ b/contracts/Velo.sol @@ -34,7 +34,7 @@ contract Velo is IVelo { function initialMint(address _recipient) external { require(msg.sender == minter && !initialMinted); initialMinted = true; - _mint(_recipient, 400 * 1e6 * 1e18); //#settings + _mint(_recipient, 300 * 1e6 * 1e18); //#settings } function approve(address _spender, uint _value) external returns (bool) { From ffec16b1c7aef71ec18581ff669f2cb9ab368ea3 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 23:15:05 +0000 Subject: [PATCH 045/156] feat: Rename token --- contracts/Velo.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Velo.sol b/contracts/Velo.sol index 19b7a4ca..29eae077 100644 --- a/contracts/Velo.sol +++ b/contracts/Velo.sol @@ -5,8 +5,8 @@ import "contracts/interfaces/IVelo.sol"; contract Velo is IVelo { - string public constant name = "Velodrome"; - string public constant symbol = "VELO"; + string public constant name = "Velocimeter"; + string public constant symbol = "FLOW"; uint8 public constant decimals = 18; uint public totalSupply = 0; From 3dd8acf292b4aa81b730b01e893ae65084d0dc51 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 23:19:32 +0000 Subject: [PATCH 046/156] refactor: Move initialMint to constructor --- contracts/Velo.sol | 12 ++---------- tasks/deploy/op.ts | 6 ------ 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/contracts/Velo.sol b/contracts/Velo.sol index 29eae077..9aa1a0d1 100644 --- a/contracts/Velo.sol +++ b/contracts/Velo.sol @@ -13,15 +13,14 @@ contract Velo is IVelo { mapping(address => uint) public balanceOf; mapping(address => mapping(address => uint)) public allowance; - bool public initialMinted; address public minter; event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); - constructor() { + constructor(address initialSupplyRecipient) { minter = msg.sender; - _mint(msg.sender, 0); + _mint(initialSupplyRecipient, 300 * 1e6 * 1e18); } // No checks as its meant to be once off to set minting rights to BaseV1 Minter @@ -30,13 +29,6 @@ contract Velo is IVelo { minter = _minter; } - // NFTs are minted from this amount as well now - function initialMint(address _recipient) external { - require(msg.sender == minter && !initialMinted); - initialMinted = true; - _mint(_recipient, 300 * 1e6 * 1e18); //#settings - } - function approve(address _spender, uint _value) external returns (bool) { allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index a0e6751e..95313c45 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -117,9 +117,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( // Airdrop // Initialize - await velo.initialMint(OP_CONFIG.teamEOA); - console.log("Initial minted"); - await velo.setMinter(minter.address); console.log("Minter set"); @@ -141,9 +138,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( await distributor.setDepositor(minter.address); console.log("Depositor set"); - await receiver.setTeam(OP_CONFIG.teamMultisig) - console.log("Team set for receiver"); - await governor.setTeam(OP_CONFIG.teamMultisig) console.log("Team set for governor"); From b9bea6f3bb250f29a48a6ac2605ffac52f554ef0 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 23:27:36 +0000 Subject: [PATCH 047/156] refactor: Rename Velo to Flow --- contracts/{Velo.sol => Flow.sol} | 4 +-- contracts/Minter.sol | 30 +++++++++---------- contracts/VeArtProxy.sol | 2 +- contracts/interfaces/{IVelo.sol => IFlow.sol} | 2 +- package.json | 4 +-- readme.md | 5 ++-- tasks/deploy/op.ts | 18 +++++------ test/BaseTest.sol | 10 +++---- test/ExternalBribes.t.sol | 2 +- test/Imbalance.t.sol | 2 +- test/KillGauges.t.sol | 4 +-- test/LPRewards.t.sol | 2 +- test/Minter.t.sol | 2 +- test/MinterTeamEmissions.t.sol | 2 +- test/Oracle.t.sol | 2 +- test/Pair.t.sol | 8 ++--- test/Staking.t.sol | 4 +-- test/VeloGovernor.t.sol | 2 +- test/VeloVoting.t.sol | 2 +- test/VotingEscrow.t.sol | 2 +- test/WashTrade.t.sol | 2 +- test/WrappedExternalBribes.t.sol | 2 +- test/utils/TestOwner.sol | 2 +- 23 files changed, 57 insertions(+), 58 deletions(-) rename contracts/{Velo.sol => Flow.sol} (97%) rename contracts/interfaces/{IVelo.sol => IFlow.sol} (96%) diff --git a/contracts/Velo.sol b/contracts/Flow.sol similarity index 97% rename from contracts/Velo.sol rename to contracts/Flow.sol index 9aa1a0d1..f9c48e73 100644 --- a/contracts/Velo.sol +++ b/contracts/Flow.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.13; -import "contracts/interfaces/IVelo.sol"; +import "contracts/interfaces/IFlow.sol"; -contract Velo is IVelo { +contract Flow is IFlow { string public constant name = "Velocimeter"; string public constant symbol = "FLOW"; diff --git a/contracts/Minter.sol b/contracts/Minter.sol index c1034614..6ee5e8e2 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -5,7 +5,7 @@ import "openzeppelin-contracts/contracts/utils/math/Math.sol"; import "contracts/interfaces/IMinter.sol"; import "contracts/interfaces/IRewardsDistributor.sol"; -import "contracts/interfaces/IVelo.sol"; +import "contracts/interfaces/IFlow.sol"; import "contracts/interfaces/IVoter.sol"; import "contracts/interfaces/IVotingEscrow.sol"; @@ -16,11 +16,11 @@ contract Minter is IMinter { uint internal constant EMISSION = 990; uint internal constant TAIL_EMISSION = 2; uint internal constant PRECISION = 1000; - IVelo public immutable _velo; + IFlow public immutable _flow; IVoter public immutable _voter; IVotingEscrow public immutable _ve; IRewardsDistributor public immutable _rewards_distributor; - uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M VELO (VELO has 18 decimals) + uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M FLOW (FLOW has 18 decimals) uint public active_period; uint internal constant LOCK = 86400 * 7 * 52 * 4; @@ -40,7 +40,7 @@ contract Minter is IMinter { initializer = msg.sender; team = msg.sender; teamRate = 30; // 30 bps = 3% - _velo = IVelo(IVotingEscrow(__ve).token()); + _flow = IFlow(IVotingEscrow(__ve).token()); _voter = IVoter(__voter); _ve = IVotingEscrow(__ve); _rewards_distributor = IRewardsDistributor(__rewards_distributor); @@ -53,8 +53,8 @@ contract Minter is IMinter { uint max // sum amounts / max = % ownership of top protocols, so if initial 20m is distributed, and target is 25% protocol ownership, then max - 4 x 20m = 80m ) external { require(initializer == msg.sender); - _velo.mint(address(this), max); - _velo.approve(address(_ve), type(uint).max); + _flow.mint(address(this), max); + _flow.approve(address(_ve), type(uint).max); for (uint i = 0; i < claimants.length; i++) { _ve.create_lock_for(amounts[i], LOCK, claimants[i]); } @@ -80,7 +80,7 @@ contract Minter is IMinter { // calculate circulating supply as total token supply - locked supply function circulating_supply() public view returns (uint) { - return _velo.totalSupply() - _ve.totalSupply(); + return _flow.totalSupply() - _ve.totalSupply(); } // emission calculation is 1% of available supply to mint adjusted by circulating / total supply @@ -101,11 +101,11 @@ contract Minter is IMinter { // calculate inflation and adjust ve balances accordingly function calculate_growth(uint _minted) public view returns (uint) { uint _veTotal = _ve.totalSupply(); - uint _veloTotal = _velo.totalSupply(); + uint _flowTotal = _flow.totalSupply(); return - (((((_minted * _veTotal) / _veloTotal) * _veTotal) / _veloTotal) * + (((((_minted * _veTotal) / _flowTotal) * _veTotal) / _flowTotal) * _veTotal) / - _veloTotal / + _flowTotal / 2; } @@ -121,17 +121,17 @@ contract Minter is IMinter { uint _teamEmissions = (teamRate * (_growth + weekly)) / (PRECISION - teamRate); uint _required = _growth + weekly + _teamEmissions; - uint _balanceOf = _velo.balanceOf(address(this)); + uint _balanceOf = _flow.balanceOf(address(this)); if (_balanceOf < _required) { - _velo.mint(address(this), _required - _balanceOf); + _flow.mint(address(this), _required - _balanceOf); } - require(_velo.transfer(team, _teamEmissions)); - require(_velo.transfer(address(_rewards_distributor), _growth)); + require(_flow.transfer(team, _teamEmissions)); + require(_flow.transfer(address(_rewards_distributor), _growth)); _rewards_distributor.checkpoint_token(); // checkpoint token balance that was just minted in rewards distributor _rewards_distributor.checkpoint_total_supply(); // checkpoint supply - _velo.approve(address(_voter), weekly); + _flow.approve(address(_voter), weekly); _voter.notifyRewardAmount(weekly); emit Mint(msg.sender, weekly, circulating_supply(), circulating_emission()); diff --git a/contracts/VeArtProxy.sol b/contracts/VeArtProxy.sol index 505149ac..db5ee78a 100644 --- a/contracts/VeArtProxy.sol +++ b/contracts/VeArtProxy.sol @@ -33,7 +33,7 @@ contract VeArtProxy is IVeArtProxy { output = string(abi.encodePacked(output, "locked_end ", toString(_locked_end), '')); output = string(abi.encodePacked(output, "value ", toString(_value), '')); - string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "lock #', toString(_tokenId), '", "description": "Velodrome locks, can be used to boost gauge yields, vote on token emission, and receive bribes", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}')))); + string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "lock #', toString(_tokenId), '", "description": "Velocimeter locks, can be used to boost gauge yields, vote on token emission, and receive bribes", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}')))); output = string(abi.encodePacked('data:application/json;base64,', json)); } } diff --git a/contracts/interfaces/IVelo.sol b/contracts/interfaces/IFlow.sol similarity index 96% rename from contracts/interfaces/IVelo.sol rename to contracts/interfaces/IFlow.sol index 8c8d1e33..ac81b10b 100644 --- a/contracts/interfaces/IVelo.sol +++ b/contracts/interfaces/IFlow.sol @@ -1,6 +1,6 @@ pragma solidity 0.8.13; -interface IVelo { +interface IFlow { function totalSupply() external view returns (uint); function balanceOf(address) external view returns (uint); function approve(address spender, uint value) external returns (bool); diff --git a/package.json b/package.json index dd8e722d..a2b47d93 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "velodrome", + "name": "velocimeter", "version": "1.0.0", - "description": "Base layer AMM on Optimism", + "description": "Base layer AMM on Canto", "directories": { "lib": "lib" }, diff --git a/readme.md b/readme.md index 6afe5d2c..d4bd97ef 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ -# Velodrome +# Velocimeter -This repo contains the contracts for Velodrome Finance, an AMM on Optimism inspired by Solidly. +This repo contains the contracts for Velocimeter Finance, an AMM on Optimism inspired by Solidly. ## Testing @@ -38,7 +38,6 @@ The Velodrome team engaged with Code 4rena for a security review. The results of | Name | Address | | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ | | WETH | [0x4200000000000000000000000000000000000006](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000006#code) | -| Velo | [0x3c8B650257cFb5f272f799F5e2b4e65093a11a05](https://optimistic.etherscan.io/address/0x3c8B650257cFb5f272f799F5e2b4e65093a11a05#code) | | PairFactory | [0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746](https://optimistic.etherscan.io/address/0x25CbdDb98b35ab1FF77413456B31EC81A6B6B746#code) | | BribeFactory | [0xA84EA94Aa705F7d009CDDF2a60f65c0d446b748E](https://optimistic.etherscan.io/address/0xA84EA94Aa705F7d009CDDF2a60f65c0d446b748E#code) | | GaugeFactory | [0xC5be2c918EB04B091962fDF095A217A55CFA42C5](https://optimistic.etherscan.io/address/0xC5be2c918EB04B091962fDF095A217A55CFA42C5#code) | diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index 95313c45..cb11ded2 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -13,7 +13,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( // Load const [ - Velo, + Velocimeter, GaugeFactory, BribeFactory, PairFactory, @@ -26,7 +26,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( Minter, VeloGovernor, ] = await Promise.all([ - ethers.getContractFactory("Velo"), + ethers.getContractFactory("Velocimeter"), ethers.getContractFactory("GaugeFactory"), ethers.getContractFactory("BribeFactory"), ethers.getContractFactory("PairFactory"), @@ -40,9 +40,9 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ethers.getContractFactory("VeloGovernor"), ]); - const velo = await Velo.deploy(); - await velo.deployed(); - console.log("Velo deployed to: ", velo.address); + const flow = await Velocimeter.deploy(); + await flow.deployed(); + console.log("FLOW deployed to: ", flow.address); const gaugeFactory = await GaugeFactory.deploy(); await gaugeFactory.deployed(); @@ -70,10 +70,10 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( await artProxy.deployed(); console.log("VeArtProxy deployed to: ", artProxy.address); - const escrow = await VotingEscrow.deploy(velo.address, artProxy.address); + const escrow = await VotingEscrow.deploy(flow.address, artProxy.address); await escrow.deployed(); console.log("VotingEscrow deployed to: ", escrow.address); - console.log("Args: ", velo.address, artProxy.address, "\n"); + console.log("Args: ", flow.address, artProxy.address, "\n"); const distributor = await RewardsDistributor.deploy(escrow.address); await distributor.deployed(); @@ -117,7 +117,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( // Airdrop // Initialize - await velo.setMinter(minter.address); + await flow.setMinter(minter.address); console.log("Minter set"); await pairFactory.setPauser(OP_CONFIG.teamMultisig); @@ -142,7 +142,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( console.log("Team set for governor"); // Whitelist - const nativeToken = [velo.address]; + const nativeToken = [flow.address]; const tokenWhitelist = nativeToken.concat(OP_CONFIG.tokenWhitelist); await voter.initialize(tokenWhitelist, minter.address); console.log("Whitelist set"); diff --git a/test/BaseTest.sol b/test/BaseTest.sol index a098075f..958ae273 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -13,7 +13,7 @@ import "contracts/Minter.sol"; import "contracts/Pair.sol"; import "contracts/RewardsDistributor.sol"; import "contracts/Router.sol"; -import "contracts/Velo.sol"; +import "contracts/Flow.sol"; import "contracts/VelodromeLibrary.sol"; import "contracts/Voter.sol"; import "contracts/VeArtProxy.sol"; @@ -43,7 +43,7 @@ abstract contract BaseTest is Test, TestOwner { MockERC20 FRAX; MockERC20 DAI; TestWETH WETH; // Mock WETH token - Velo VELO; + Flow FLOW; MockERC20 WEVE; MockERC20 LR; // late reward TestToken stake; @@ -68,7 +68,7 @@ abstract contract BaseTest is Test, TestOwner { USDC = new MockERC20("USDC", "USDC", 6); FRAX = new MockERC20("FRAX", "FRAX", 18); DAI = new MockERC20("DAI", "DAI", 18); - VELO = new Velo(); + FLOW = new Flow(msg.sender); WEVE = new MockERC20("WEVE", "WEVE", 18); LR = new MockERC20("LR", "LR", 18); WETH = new TestWETH(); @@ -83,9 +83,9 @@ abstract contract BaseTest is Test, TestOwner { } } - function mintVelo(address[] memory _accounts, uint256[] memory _amounts) public { + function mintFlow(address[] memory _accounts, uint256[] memory _amounts) public { for (uint256 i = 0; i < _amounts.length; i++) { - VELO.mint(_accounts[i], _amounts[i]); + FLOW.mint(_accounts[i], _amounts[i]); } } diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index 2b04d780..7191a5fb 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -24,7 +24,7 @@ contract ExternalBribesTest is BaseTest { amounts[0] = 2e25; amounts[1] = 1e25; amounts[2] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/Imbalance.t.sol b/test/Imbalance.t.sol index f9c9cd12..cc00ee4c 100644 --- a/test/Imbalance.t.sol +++ b/test/Imbalance.t.sol @@ -17,7 +17,7 @@ contract ImbalanceTest is BaseTest { mintStables(); uint256[] memory amounts = new uint256[](1); amounts[0] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); } diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index 0108fe75..1fc3ee28 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -23,7 +23,7 @@ contract KillGaugesTest is BaseTest { amounts[0] = 2e25; amounts[1] = 1e25; amounts[2] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); @@ -136,7 +136,7 @@ contract KillGaugesTest is BaseTest { staking.notifyRewardAmount(claimable); address[] memory gauges = new address[](1); gauges[0] = address(gauge); - + voter.killGauge(address(gauge)); voter.updateFor(gauges); diff --git a/test/LPRewards.t.sol b/test/LPRewards.t.sol index 8c9140ef..d1ddc7e9 100644 --- a/test/LPRewards.t.sol +++ b/test/LPRewards.t.sol @@ -18,7 +18,7 @@ contract LPRewardsTest is BaseTest { uint256[] memory amounts = new uint256[](2); amounts[0] = 2 * TOKEN_1M; // use 1/2 for veNFT position amounts[1] = TOKEN_1M; - mintVelo(owners, amounts); + mintFlow(owners, amounts); // give owner1 veVELO VeArtProxy artProxy = new VeArtProxy(); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index f36d4d53..fa96fd6b 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -20,7 +20,7 @@ contract MinterTest is BaseTest { mintStables(); uint256[] memory amounts = new uint256[](1); amounts[0] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index 921ddcff..c7fe97a7 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -22,7 +22,7 @@ contract MinterTeamEmissions is BaseTest { uint256[] memory amountsVelo = new uint256[](2); amountsVelo[0] = 1e25; amountsVelo[1] = 1e25; - mintVelo(owners, amountsVelo); + mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/Oracle.t.sol b/test/Oracle.t.sol index f150181a..5e554e50 100644 --- a/test/Oracle.t.sol +++ b/test/Oracle.t.sol @@ -12,7 +12,7 @@ contract OracleTest is BaseTest { mintStables(); uint256[] memory amounts = new uint256[](1); amounts[0] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); escrow = VotingEscrow(address(VELO)); } diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 90893de9..30b1db42 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -27,7 +27,7 @@ contract PairTest is BaseTest { amounts[0] = 2e25; amounts[1] = 1e25; amounts[2] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); @@ -57,7 +57,7 @@ contract PairTest is BaseTest { function votingEscrowViews() public { increaseLock(); - + uint256 block_ = escrow.block_number(); assertEq(escrow.balanceOfAtNFT(1, block_), escrow.balanceOfNFT(1)); assertEq(escrow.totalSupplyAt(block_), escrow.totalSupply()); @@ -429,7 +429,7 @@ contract PairTest is BaseTest { function gaugePokeHacking() public { voteHacking(); - + assertEq(voter.usedWeights(1), 0); assertEq(voter.votes(1, address(pair)), 0); voter.poke(1); @@ -439,7 +439,7 @@ contract PairTest is BaseTest { function gaugeVoteAndBribeBalanceOf() public { gaugePokeHacking(); - + address[] memory pools = new address[](2); pools[0] = address(pair); pools[1] = address(pair2); diff --git a/test/Staking.t.sol b/test/Staking.t.sol index 6fefea2b..5e2e8110 100644 --- a/test/Staking.t.sol +++ b/test/Staking.t.sol @@ -18,7 +18,7 @@ contract StakingTest is BaseTest { amounts[0] = 1e27; amounts[1] = 1e27; amounts[2] = 1e27; - mintVelo(owners, amounts); + mintFlow(owners, amounts); mintLR(owners, amounts); mintStake(owners, amounts); escrow = new TestVotingEscrow(address(VELO)); @@ -189,7 +189,7 @@ contract StakingTest is BaseTest { function notifyRewardsAndCompareOwner2() public { notifyRewardsAndCompareOwner1(); - + owner2.withdrawStake(address(staking), 1e21); owner2.withdrawGauge(address(gauge), 1e21); owner2.approve(address(stake), address(staking), 1e21); diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol index c056f114..55e9d874 100644 --- a/test/VeloGovernor.t.sol +++ b/test/VeloGovernor.t.sol @@ -22,7 +22,7 @@ contract VeloGovernorTest is BaseTest { amounts[0] = 2e25; amounts[1] = 1e25; amounts[2] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 443d5fdf..297a652e 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -22,7 +22,7 @@ contract VeloVotingTest is BaseTest { uint256[] memory amountsVelo = new uint256[](2); amountsVelo[0] = 1e25; amountsVelo[1] = 1e25; - mintVelo(owners, amountsVelo); + mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/VotingEscrow.t.sol b/test/VotingEscrow.t.sol index 4766b63d..e8d29123 100644 --- a/test/VotingEscrow.t.sol +++ b/test/VotingEscrow.t.sol @@ -12,7 +12,7 @@ contract VotingEscrowTest is BaseTest { mintStables(); uint256[] memory amounts = new uint256[](1); amounts[0] = 1e21; - mintVelo(owners, amounts); + mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/WashTrade.t.sol b/test/WashTrade.t.sol index bc026e78..c8895ac9 100644 --- a/test/WashTrade.t.sol +++ b/test/WashTrade.t.sol @@ -19,7 +19,7 @@ contract WashTradeTest is BaseTest { mintStables(); uint256[] memory amounts = new uint256[](1); amounts[0] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index 69efadc0..0c3c0a3f 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -26,7 +26,7 @@ contract WrappedExternalBribesTest is BaseTest { amounts[0] = 2e25; amounts[1] = 1e25; amounts[2] = 1e25; - mintVelo(owners, amounts); + mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(VELO), address(artProxy)); diff --git a/test/utils/TestOwner.sol b/test/utils/TestOwner.sol index bad07794..7f3ce4ec 100644 --- a/test/utils/TestOwner.sol +++ b/test/utils/TestOwner.sol @@ -5,7 +5,7 @@ import "contracts/Gauge.sol"; import "contracts/Minter.sol"; import "contracts/Pair.sol"; import "contracts/Router.sol"; -import "contracts/Velo.sol"; +import "contracts/Flow.sol"; import "contracts/VotingEscrow.sol"; import "utils/TestStakingRewards.sol"; import "utils/TestVotingEscrow.sol"; From 721e61544404d23b82f0c9f964b14f04766eda93 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 23:30:25 +0000 Subject: [PATCH 048/156] fix: Remove claim from IFlow --- contracts/interfaces/IFlow.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/interfaces/IFlow.sol b/contracts/interfaces/IFlow.sol index ac81b10b..dda026eb 100644 --- a/contracts/interfaces/IFlow.sol +++ b/contracts/interfaces/IFlow.sol @@ -8,5 +8,4 @@ interface IFlow { function transferFrom(address,address,uint) external returns (bool); function mint(address, uint) external returns (bool); function minter() external returns (address); - function claim(address, uint) external returns (bool); } From 584a6add6e1dff22c68433071121b1c1f630f8a8 Mon Sep 17 00:00:00 2001 From: coolie Date: Fri, 3 Mar 2023 23:31:14 +0000 Subject: [PATCH 049/156] docs: Optimism -> Canto --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d4bd97ef..d5d50e01 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # Velocimeter -This repo contains the contracts for Velocimeter Finance, an AMM on Optimism inspired by Solidly. +This repo contains the contracts for Velocimeter Finance, an AMM on Canto inspired by Solidly. ## Testing From c1e7f1fcec2be8934516a42872240f3d24540303 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 4 Mar 2023 21:17:38 +0800 Subject: [PATCH 050/156] chore: amend gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4e5a6c1b..9cd9ba7b 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,4 @@ scripts/xbribes Flattened.sol lib/openzeppelin-contracts lib/forge-std -lib/forge-std +lib/ds-test From 0dfc2e00e6cd429d974baa4918651fbe95935e29 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 4 Mar 2023 21:24:03 +0800 Subject: [PATCH 051/156] fix: add changes --- contracts/ExternalBribe.sol | 2 - contracts/FlowConvertor.sol | 73 ++++++++++ contracts/FlowVestor.sol | 189 +++++++++++++++++++++++++ contracts/Router.sol | 137 +++++++++++++++++- contracts/WrappedExternalBribe.sol | 2 - contracts/interfaces/IGaugeFactory.sol | 2 +- test/BaseTest.sol | 6 +- test/Pair.t.sol | 18 +-- test/Staking.t.sol | 2 +- 9 files changed, 412 insertions(+), 19 deletions(-) create mode 100644 contracts/FlowConvertor.sol create mode 100644 contracts/FlowVestor.sol diff --git a/contracts/ExternalBribe.sol b/contracts/ExternalBribe.sol index 9161e292..41ce2031 100644 --- a/contracts/ExternalBribe.sol +++ b/contracts/ExternalBribe.sol @@ -16,8 +16,6 @@ contract ExternalBribe is IBribe { uint internal constant DURATION = 7 days; // rewards are released over the voting period uint internal constant MAX_REWARD_TOKENS = 16; - uint internal constant PRECISION = 10 ** 18; - uint public totalSupply; mapping(uint => uint) public balanceOf; mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch; diff --git a/contracts/FlowConvertor.sol b/contracts/FlowConvertor.sol new file mode 100644 index 00000000..116e5460 --- /dev/null +++ b/contracts/FlowConvertor.sol @@ -0,0 +1,73 @@ +pragma solidity 0.8.13; + +import "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; +import "openzeppelin-contracts/contracts/access/Ownable.sol"; + +/** + * @dev This contract allow users to convert one token to another. + * It requires both tokens to have valid contract addresses. + * It requires that it is filled up first with liquid v2 tokens., they dont need to be exact. + * Any tokens that get sent here accidently can be sent back out, except v1 token. + */ +contract FlowConvertor is Ownable { + address public immutable v1; + address public immutable v2; + + constructor(address _v1, address _v2) { + v1 = _v1; + v2 = _v2; + } + + /** + * @dev Transfers ERC20 v1 from user to contract, and Transfer ERC20 v2 to user, 1 to 1. + */ + function redeem(uint256 amount) public { + require(amount > 0, "you dont have and v1 tokens"); + SafeERC20.safeTransferFrom( + IERC20(v1), + _msgSender(), + address(this), + amount + ); + SafeERC20.safeTransferFrom( + IERC20(v2), + address(this), + _msgSender(), + amount + ); + } + + /** + * @dev Transfers ERC20 v1 from user to contract, and Transfer ERC20 v2 to an address specified, 1 to 1. + */ + function redeemTo(address _to, uint256 amount) public { + require(amount > 0, "you dont have and v1 tokens"); + SafeERC20.safeTransferFrom( + IERC20(v1), + _msgSender(), + address(this), + amount + ); + SafeERC20.safeTransferFrom(IERC20(v2), address(this), _to, amount); + } + + /** + * @dev Allows owner to clean out the contract of ANY tokens including v2, but not v1 + */ + function inCaseTokensGetStuck( + address _token, + address _to, + uint256 _amount + ) public onlyOwner { + require(_token != address(v1), "these tkns are essentially burnt"); + SafeERC20.safeTransfer(IERC20(_token), _to, _amount); + } + + /** + * @dev Allows owner sweep out all the remaining v2 tokens. + */ + function sweepV2(address _to) public onlyOwner { + uint256 _surplus = IERC20(v2).balanceOf(address(this)); + SafeERC20.safeTransfer(IERC20(v2), _to, _surplus); + } +} diff --git a/contracts/FlowVestor.sol b/contracts/FlowVestor.sol new file mode 100644 index 00000000..2ee2f53d --- /dev/null +++ b/contracts/FlowVestor.sol @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: MIT AND AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import "openzeppelin-contracts/contracts/access/Ownable.sol"; +import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; + +// Inspired by https://github.com/vetherasset/vader-protocol-v2/blob/main/contracts/tokens/vesting/LinearVesting.sol +/** + * @dev Implementation of the Linear Vesting + * + * The straightforward vesting contract that gradually releases a + * fixed supply of tokens to multiple vest parties over a 1 year + * window. + * + * The token expects the {begin} hook to be invoked the moment + * it is supplied with the necessary amount of tokens to vest + */ +contract FlowVestor is Ownable { + address public revokeTo; + /* ========== CONSTANTS ========== */ + + address internal constant _ZERO_ADDRESS = address(0); + + uint256 internal constant _ONE_YEAR = 365 days; + + /* ========== FLOW ALLOCATION ========== */ + + // The FLOW token + IERC20 public immutable FLOW; + + /* ========== VESTING ========== */ + + // Vesting Duration + uint256 public constant VESTING_DURATION = 1 * _ONE_YEAR; + + /* ========== STRUCTS ========== */ + + // Struct of a vesting member, tight-packed to 256-bits + struct Vester { + uint192 amount; + uint64 lastClaim; + uint128 start; + uint128 end; + } + + /* ========== EVENTS ========== */ + + event RevokeToUpdated(address oldAddress, address newAddress); + event VestingCreated(address user, uint256 amount); + event VestingCancelled(address user, uint256 amount); + event Vested(address indexed from, uint256 amount); + + /* ========== STATE VARIABLES ========== */ + + // The status of each vesting member (Vester) + mapping(address => Vester) public vest; + + /* ========== CONSTRUCTOR ========== */ + + /** + * @dev Initializes the FLOW token address + * + * Additionally, it transfers ownership to the Owner contract that needs to consequently + * initiate the vesting period via {begin} after it mints the necessary amount to the contract. + */ + constructor(address _admin, address _FLOW) { + require(_admin != _ZERO_ADDRESS, "Misconfiguration"); + FLOW = IERC20(_FLOW); + transferOwnership(_admin); + } + + /* ========== VIEWS ========== */ + + /** + * @dev Returns the amount a user can claim at a given point in time. + * + * Requirements: + * - the vesting period has started + */ + function getClaim(address _vester) + external + view + returns (uint256 vestedAmount) + { + Vester memory vester = vest[_vester]; + return + _getClaim( + vester.amount, + vester.lastClaim, + vester.start, + vester.end + ); + } + + /* ========== MUTATIVE FUNCTIONS ========== */ + + /** + * @dev Allows a user to claim their pending vesting amount of the vested claim + * + * Emits a {Vested} event indicating the user who claimed their vested tokens + * as well as the amount that was vested. + * + * Requirements: + * + * - the vesting period has started + * - the caller must have a non-zero vested amount + */ + function claim() external returns (uint256 vestedAmount) { + Vester memory vester = vest[msg.sender]; + + require(vester.start != 0, "Not Started"); + + require(vester.start < block.timestamp, "Not Started Yet"); + + vestedAmount = _getClaim( + vester.amount, + vester.lastClaim, + vester.start, + vester.end + ); + + require(vestedAmount != 0, "Nothing to claim"); + + vester.amount -= uint192(vestedAmount); + vester.lastClaim = uint64(block.timestamp); + + vest[msg.sender] = vester; + + emit Vested(msg.sender, vestedAmount); + + FLOW.transfer(msg.sender, vestedAmount); + } + + /* ========== RESTRICTED FUNCTIONS ========== */ + + /** + * @dev Adds a new vesting schedule to the contract. + * + * Requirements: + * - Only {owner} can call. + */ + function vestFor(address user, uint256 amount) external onlyOwner { + require(amount <= type(uint192).max, "Amount Overflows uint192"); + require(vest[user].amount == 0, "Already a vester"); + vest[user] = Vester( + uint192(amount), + 0, + uint128(block.timestamp), + uint128(block.timestamp + VESTING_DURATION) + ); + FLOW.transferFrom(msg.sender, address(this), amount); + + emit VestingCreated(user, amount); + } + + function cancelVest(address user) external onlyOwner { + require(revokeTo != address(0), "0 revoke to address"); + uint256 amount = vest[user].amount; + require(amount > 0, "Not a vester"); + require( + FLOW.balanceOf(address(this)) >= amount, + "Insufficient FLOW balance" + ); + delete vest[user]; + FLOW.transfer(revokeTo, amount); + + emit VestingCancelled(user, amount); + } + + function setRevokeTo(address _revokeTo) external onlyOwner { + require(_revokeTo != address(0), "0 address"); + emit RevokeToUpdated(revokeTo, _revokeTo); + revokeTo = _revokeTo; + } + + /* ========== PRIVATE FUNCTIONS ========== */ + + function _getClaim( + uint256 amount, + uint256 lastClaim, + uint256 _start, + uint256 _end + ) private view returns (uint256) { + if (block.timestamp >= _end) return amount; + if (lastClaim == 0) lastClaim = _start; + + return (amount * (block.timestamp - lastClaim)) / (_end - lastClaim); + } +} diff --git a/contracts/Router.sol b/contracts/Router.sol index 46efa97c..03e3beff 100644 --- a/contracts/Router.sol +++ b/contracts/Router.sol @@ -69,7 +69,7 @@ contract Router is IRouter { } // performs chained getAmountOut calculations on any number of pairs - function getAmountOut(uint amountIn, address tokenIn, address tokenOut) external view returns (uint amount, bool stable) { + function getAmountOut(uint amountIn, address tokenIn, address tokenOut) public view returns (uint amount, bool stable) { address pair = pairFor(tokenIn, tokenOut, true); uint amountStable; uint amountVolatile; @@ -83,6 +83,16 @@ contract Router is IRouter { return amountStable > amountVolatile ? (amountStable, true) : (amountVolatile, false); } + //@override + //getAmountOut : bool stable + //Gets exact output for specific pair-type(S|V) + function getAmountOut(uint amountIn, address tokenIn, address tokenOut, bool stable) public view returns (uint amount) { + address pair = pairFor(tokenIn, tokenOut, stable); + if (IPairFactory(factory).isPair(pair)) { + amount = IPair(pair).getAmountOut(amountIn, tokenIn); + } + } + // performs chained getAmountOut calculations on any number of pairs function getAmountsOut(uint amountIn, route[] memory routes) public view returns (uint[] memory amounts) { require(routes.length >= 1, 'Router: INVALID_PATH'); @@ -420,4 +430,129 @@ contract Router is IRouter { token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool)))); } + + // Experimental Extension [eth.guru/solidly/Router02] + + // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens)**** + function removeLiquidityETHSupportingFeeOnTransferTokens( + address token, + bool stable, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) public ensure(deadline) returns (uint amountToken, uint amountETH) { + (amountToken, amountETH) = removeLiquidity( + token, + address(weth), + stable, + liquidity, + amountTokenMin, + amountETHMin, + address(this), + deadline + ); + _safeTransfer(token, to, IERC20(token).balanceOf(address(this))); + weth.withdraw(amountETH); + _safeTransferETH(to, amountETH); + } + function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( + address token, + bool stable, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountToken, uint amountETH) { + address pair = pairFor(token, address(weth), stable); + uint value = approveMax ? type(uint).max : liquidity; + IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + (amountToken, amountETH) = removeLiquidityETHSupportingFeeOnTransferTokens( + token, stable, liquidity, amountTokenMin, amountETHMin, to, deadline + ); + } + // **** SWAP (supporting fee-on-transfer tokens) **** + // requires the initial amount to have already been sent to the first pair + function _swapSupportingFeeOnTransferTokens(route[] memory routes, address _to) internal virtual { + for (uint i; i < routes.length; i++) { + (address input, address output, bool stable) = (routes[i].from, routes[i].to, routes[i].stable); + (address token0,) = sortTokens(input, output); + IPair pair = IPair(pairFor(routes[i].from, routes[i].to, routes[i].stable)); + uint amountInput; + uint amountOutput; + { // scope to avoid stack too deep errors + (uint reserve0, uint reserve1,) = pair.getReserves(); + (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); + amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput; + amountOutput = pair.getAmountOut(amountInput, input); + } + (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); + address to = i < routes.length - 1 ? pairFor(routes[i+1].from, routes[i+1].to, routes[i+1].stable) : _to; + pair.swap(amount0Out, amount1Out, to, new bytes(0)); + } + } + function swapExactTokensForTokensSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + route[] calldata routes, + address to, + uint deadline + ) external ensure(deadline) { + _safeTransferFrom( + routes[0].from, + msg.sender, + pairFor(routes[0].from, routes[0].to, routes[0].stable), + amountIn + ); + uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to); + _swapSupportingFeeOnTransferTokens(routes, to); + require( + IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >= amountOutMin, + 'Router: INSUFFICIENT_OUTPUT_AMOUNT' + ); + } + function swapExactETHForTokensSupportingFeeOnTransferTokens( + uint amountOutMin, + route[] calldata routes, + address to, + uint deadline + ) + external + payable + ensure(deadline) + { + require(routes[0].from == address(weth), 'Router: INVALID_PATH'); + uint amountIn = msg.value; + weth.deposit{value: amountIn}(); + assert(weth.transfer(pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn)); + uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to); + _swapSupportingFeeOnTransferTokens(routes, to); + require( + IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >= amountOutMin, + 'Router: INSUFFICIENT_OUTPUT_AMOUNT' + ); + } + function swapExactTokensForETHSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + route[] calldata routes, + address to, + uint deadline + ) + external + ensure(deadline) + { + require(routes[routes.length - 1].to == address(weth), 'Router: INVALID_PATH'); + _safeTransferFrom( + routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn + ); + _swapSupportingFeeOnTransferTokens(routes, address(this)); + uint amountOut = IERC20(address(weth)).balanceOf(address(this)); + require(amountOut >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT'); + weth.withdraw(amountOut); + _safeTransferETH(to, amountOut); + } } diff --git a/contracts/WrappedExternalBribe.sol b/contracts/WrappedExternalBribe.sol index d784f885..d44d4ea5 100644 --- a/contracts/WrappedExternalBribe.sol +++ b/contracts/WrappedExternalBribe.sol @@ -17,8 +17,6 @@ contract WrappedExternalBribe { uint internal constant DURATION = 7 days; // rewards are released over the voting period uint internal constant MAX_REWARD_TOKENS = 16; - uint internal constant PRECISION = 10 ** 18; - mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch; mapping(address => uint) public periodFinish; mapping(address => mapping(uint => uint)) public lastEarn; diff --git a/contracts/interfaces/IGaugeFactory.sol b/contracts/interfaces/IGaugeFactory.sol index 0f54b56b..b2446467 100644 --- a/contracts/interfaces/IGaugeFactory.sol +++ b/contracts/interfaces/IGaugeFactory.sol @@ -1,5 +1,5 @@ pragma solidity 0.8.13; interface IGaugeFactory { - function createGauge(address, address, address, address, bool, address[] memory) external returns (address); + function createGauge(address, address, address, bool, address[] memory) external returns (address); } diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 958ae273..f2f5fc5d 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -43,7 +43,7 @@ abstract contract BaseTest is Test, TestOwner { MockERC20 FRAX; MockERC20 DAI; TestWETH WETH; // Mock WETH token - Flow FLOW; + Flow VELO; MockERC20 WEVE; MockERC20 LR; // late reward TestToken stake; @@ -68,7 +68,7 @@ abstract contract BaseTest is Test, TestOwner { USDC = new MockERC20("USDC", "USDC", 6); FRAX = new MockERC20("FRAX", "FRAX", 18); DAI = new MockERC20("DAI", "DAI", 18); - FLOW = new Flow(msg.sender); + VELO = new Flow(msg.sender); WEVE = new MockERC20("WEVE", "WEVE", 18); LR = new MockERC20("LR", "LR", 18); WETH = new TestWETH(); @@ -85,7 +85,7 @@ abstract contract BaseTest is Test, TestOwner { function mintFlow(address[] memory _accounts, uint256[] memory _amounts) public { for (uint256 i = 0; i < _amounts.length; i++) { - FLOW.mint(_accounts[i], _amounts[i]); + VELO.mint(_accounts[i], _amounts[i]); } } diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 30b1db42..dd08b2f0 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -417,14 +417,14 @@ contract PairTest is BaseTest { voter.vote(1, pools, weights); assertEq(voter.usedWeights(1), escrow.balanceOfNFT(1)); // within 1000 - assertEq(bribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); + assertEq(xbribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); vm.warp(block.timestamp + 1 weeks); voter.reset(1); assertLt(voter.usedWeights(1), escrow.balanceOfNFT(1)); assertEq(voter.usedWeights(1), 0); - assertEq(bribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); - assertEq(bribe.balanceOf(1), 0); + assertEq(xbribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); + assertEq(xbribe.balanceOf(1), 0); } function gaugePokeHacking() public { @@ -456,7 +456,7 @@ contract PairTest is BaseTest { console2.log(voter.usedWeights(1)); console2.log(voter.usedWeights(4)); assertFalse(voter.totalWeight() == 0); - assertFalse(bribe.balanceOf(1) == 0); + assertFalse(xbribe.balanceOf(1) == 0); } function gaugePokeHacking2() public { @@ -481,7 +481,7 @@ contract PairTest is BaseTest { voter.vote(1, pools, weights); assertEq(voter.usedWeights(1), escrow.balanceOfNFT(1)); // within 1000 - assertEq(bribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); + assertEq(xbribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); } function gaugePokeHacking3() public { @@ -506,10 +506,10 @@ contract PairTest is BaseTest { address[] memory rewards = new address[](1); rewards[0] = address(VELO); - bribe.getReward(1, rewards); + xbribe.getReward(1, rewards); vm.warp(block.timestamp + 691200); vm.roll(block.number + 1); - bribe.getReward(1, rewards); + xbribe.getReward(1, rewards); } function routerPair1GetAmountsOutAndSwapExactTokensForTokens2() public { @@ -580,7 +580,7 @@ contract PairTest is BaseTest { address[] memory rewards = new address[](2); rewards[0] = address(FRAX); rewards[1] = address(USDC); - bribe.getReward(1, rewards); + xbribe.getReward(1, rewards); address[] memory gauges = new address[](1); gauges[0] = address(gauge); @@ -714,7 +714,7 @@ contract PairTest is BaseTest { gaugeClaimRewardsAfterExpiry(); address[] memory bribes_ = new address[](1); - bribes_[0] = address(bribe); + bribes_[0] = address(xbribe); address[][] memory rewards = new address[][](1); address[] memory reward = new address[](1); reward[0] = address(DAI); diff --git a/test/Staking.t.sol b/test/Staking.t.sol index 5e2e8110..63339835 100644 --- a/test/Staking.t.sol +++ b/test/Staking.t.sol @@ -52,7 +52,7 @@ contract StakingTest is BaseTest { gaugeFactory = new GaugeFactory(); address[] memory allowedRewards = new address[](1); vm.prank(address(voter)); - gaugeFactory.createGauge(address(stake), address(owner), address(owner), address(escrow), false, allowedRewards); + gaugeFactory.createGauge(address(stake), address(owner), address(escrow), false, allowedRewards); address gaugeAddr = gaugeFactory.last_gauge(); gauge = Gauge(gaugeAddr); From 937353449a3a880b9dd23b93b2a0698572acf714 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 4 Mar 2023 21:42:53 +0800 Subject: [PATCH 052/156] feat: add owner in voting escrow --- contracts/VotingEscrow.sol | 5 +++-- test/ExternalBribes.t.sol | 2 +- test/Imbalance.t.sol | 2 +- test/KillGauges.t.sol | 2 +- test/LPRewards.t.sol | 2 +- test/Minter.t.sol | 2 +- test/MinterTeamEmissions.t.sol | 2 +- test/NFTVote.t.sol | 2 +- test/Pair.t.sol | 2 +- test/VeloGovernor.t.sol | 2 +- test/VeloVoting.t.sol | 2 +- test/VotingEscrow.t.sol | 2 +- test/WashTrade.t.sol | 2 +- test/WrappedExternalBribes.t.sol | 2 +- 14 files changed, 16 insertions(+), 15 deletions(-) diff --git a/contracts/VotingEscrow.sol b/contracts/VotingEscrow.sol index 66eff883..bd115f37 100644 --- a/contracts/VotingEscrow.sol +++ b/contracts/VotingEscrow.sol @@ -63,7 +63,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ - + address public immutable owner; address public immutable token; address public voter; address public team; @@ -88,11 +88,12 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @notice Contract constructor /// @param token_addr `VELO` token address - constructor(address token_addr, address art_proxy) { + constructor(address token_addr, address art_proxy, address _owner) { token = token_addr; voter = msg.sender; team = msg.sender; artProxy = art_proxy; + owner = _owner; point_history[0].blk = block.number; point_history[0].ts = block.timestamp; diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index 7191a5fb..1fb8eeb9 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -27,7 +27,7 @@ contract ExternalBribesTest is BaseTest { mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); deployPairFactoryAndRouter(); // deployVoter() diff --git a/test/Imbalance.t.sol b/test/Imbalance.t.sol index cc00ee4c..cc95424f 100644 --- a/test/Imbalance.t.sol +++ b/test/Imbalance.t.sol @@ -19,7 +19,7 @@ contract ImbalanceTest is BaseTest { amounts[0] = 1e25; mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); } function createLock() public { diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index 1fc3ee28..5eeee2a7 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -25,7 +25,7 @@ contract KillGaugesTest is BaseTest { amounts[2] = 1e25; mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); VELO.approve(address(escrow), 100 * TOKEN_1); escrow.create_lock(100 * TOKEN_1, 4 * 365 * 86400); diff --git a/test/LPRewards.t.sol b/test/LPRewards.t.sol index d1ddc7e9..9566dd20 100644 --- a/test/LPRewards.t.sol +++ b/test/LPRewards.t.sol @@ -22,7 +22,7 @@ contract LPRewardsTest is BaseTest { // give owner1 veVELO VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); VELO.approve(address(escrow), TOKEN_1M); escrow.create_lock(TOKEN_1M, 4 * 365 * 86400); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index fa96fd6b..35dd3b02 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -23,7 +23,7 @@ contract MinterTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index c7fe97a7..cd82d190 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -25,7 +25,7 @@ contract MinterTeamEmissions is BaseTest { mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owner); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); diff --git a/test/NFTVote.t.sol b/test/NFTVote.t.sol index 2b032673..e4b49b26 100644 --- a/test/NFTVote.t.sol +++ b/test/NFTVote.t.sol @@ -21,7 +21,7 @@ contract NFTVoteTest is BaseTest { deployCoins(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); gov = new TestL2Governance(escrow); // test variable to vote on diff --git a/test/Pair.t.sol b/test/Pair.t.sol index dd08b2f0..51bbb888 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -31,7 +31,7 @@ contract PairTest is BaseTest { mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); } function createLock() public { diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol index 55e9d874..11362057 100644 --- a/test/VeloGovernor.t.sol +++ b/test/VeloGovernor.t.sol @@ -25,7 +25,7 @@ contract VeloGovernorTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); VELO.approve(address(escrow), 97 * TOKEN_1); escrow.create_lock(97 * TOKEN_1, 4 * 365 * 86400); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 297a652e..2cc803ca 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -25,7 +25,7 @@ contract VeloVotingTest is BaseTest { mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); diff --git a/test/VotingEscrow.t.sol b/test/VotingEscrow.t.sol index e8d29123..62a4fbfb 100644 --- a/test/VotingEscrow.t.sol +++ b/test/VotingEscrow.t.sol @@ -15,7 +15,7 @@ contract VotingEscrowTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); } function testCreateLock() public { diff --git a/test/WashTrade.t.sol b/test/WashTrade.t.sol index c8895ac9..82ac79dd 100644 --- a/test/WashTrade.t.sol +++ b/test/WashTrade.t.sol @@ -22,7 +22,7 @@ contract WashTradeTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); } function createLock() public { diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index 0c3c0a3f..2c50362c 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -29,7 +29,7 @@ contract WrappedExternalBribesTest is BaseTest { mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy)); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); deployPairFactoryAndRouter(); // deployVoter() From a3fd6ed98c237f17f3e832781f35440c208bdbd3 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 4 Mar 2023 21:51:24 +0800 Subject: [PATCH 053/156] fix: fix failed tests --- test/MinterTeamEmissions.t.sol | 2 +- test/NFTVote.t.sol | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index cd82d190..0eb1b940 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -25,7 +25,7 @@ contract MinterTeamEmissions is BaseTest { mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owner); + escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); diff --git a/test/NFTVote.t.sol b/test/NFTVote.t.sol index e4b49b26..df380ef2 100644 --- a/test/NFTVote.t.sol +++ b/test/NFTVote.t.sol @@ -18,6 +18,7 @@ contract NFTVoteTest is BaseTest { FlagCondition flag; function setUp() public { + deployOwners(); deployCoins(); VeArtProxy artProxy = new VeArtProxy(); From 3d859baaddc3a9dd41bc37de85a82d31ae627678 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 13:53:41 +0000 Subject: [PATCH 054/156] refactor: Rename VELO to FLOW and fixed a test --- contracts/VotingEscrow.sol | 2 +- tasks/deploy/constants/optimismConfig.ts | 4 +- tasks/deploy/op.ts | 4 +- test/BaseTest.sol | 6 +- test/ExternalBribes.t.sol | 10 +- test/Imbalance.t.sol | 14 +-- test/KillGauges.t.sol | 22 ++-- test/LPRewards.t.sol | 10 +- test/Minter.t.sol | 22 ++-- test/MinterTeamEmissions.t.sol | 46 +++---- test/NFTVote.t.sol | 7 +- test/Oracle.t.sol | 2 +- test/Pair.t.sol | 110 ++++++++-------- test/Staking.t.sol | 152 +++++++++++------------ test/VeloGovernor.t.sol | 12 +- test/VeloVoting.t.sol | 28 ++--- test/VotingEscrow.t.sol | 12 +- test/WashTrade.t.sol | 14 +-- test/WrappedExternalBribes.t.sol | 10 +- 19 files changed, 244 insertions(+), 243 deletions(-) diff --git a/contracts/VotingEscrow.sol b/contracts/VotingEscrow.sol index bd115f37..4e8a9abf 100644 --- a/contracts/VotingEscrow.sol +++ b/contracts/VotingEscrow.sol @@ -87,7 +87,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint internal tokenId; /// @notice Contract constructor - /// @param token_addr `VELO` token address + /// @param token_addr `FLOW` token address constructor(address token_addr, address art_proxy, address _owner) { token = token_addr; voter = msg.sender; diff --git a/tasks/deploy/constants/optimismConfig.ts b/tasks/deploy/constants/optimismConfig.ts index 8eb91894..f25a4c4d 100644 --- a/tasks/deploy/constants/optimismConfig.ts +++ b/tasks/deploy/constants/optimismConfig.ts @@ -54,13 +54,13 @@ const optimismConfig = { "0x8aE125E8653821E851F12A49F7765db9a9ce7384", // DOLA "0x10010078a54396F62c96dF8532dc2B4847d47ED3", // HND // "", // BTRFLY -- N/A - // "", // pxVELO -- N/A + // "", // pxFLOW -- N/A "0xc40F949F8a4e094D1b49a23ea9241D289B7b2819", // LUSD // "", // wstETH -- N/A // "", // HOP -- N/A ], partnerAddrs: [ - TEAM_EOA, // VELO + TEAM_EOA, // FLOW "0x4a84675512949f81EBFEAAcC6C00D03eDd329de5", // OP TEAM_EOA, // SNX -- custodied "0xa283139017a2f5BAdE8d8e25412C600055D318F8", // INV diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index cb11ded2..9e7993c3 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -147,13 +147,13 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( await voter.initialize(tokenWhitelist, minter.address); console.log("Whitelist set"); - // Initial veVELO distro + // Initial veFLOW distro await minter.initialize( OP_CONFIG.partnerAddrs, OP_CONFIG.partnerAmts, OP_CONFIG.partnerMax ); - console.log("veVELO distributed"); + console.log("veFLOW distributed"); await minter.setTeam(OP_CONFIG.teamMultisig) console.log("Team set for minter"); diff --git a/test/BaseTest.sol b/test/BaseTest.sol index f2f5fc5d..958ae273 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -43,7 +43,7 @@ abstract contract BaseTest is Test, TestOwner { MockERC20 FRAX; MockERC20 DAI; TestWETH WETH; // Mock WETH token - Flow VELO; + Flow FLOW; MockERC20 WEVE; MockERC20 LR; // late reward TestToken stake; @@ -68,7 +68,7 @@ abstract contract BaseTest is Test, TestOwner { USDC = new MockERC20("USDC", "USDC", 6); FRAX = new MockERC20("FRAX", "FRAX", 18); DAI = new MockERC20("DAI", "DAI", 18); - VELO = new Flow(msg.sender); + FLOW = new Flow(msg.sender); WEVE = new MockERC20("WEVE", "WEVE", 18); LR = new MockERC20("LR", "LR", 18); WETH = new TestWETH(); @@ -85,7 +85,7 @@ abstract contract BaseTest is Test, TestOwner { function mintFlow(address[] memory _accounts, uint256[] memory _amounts) public { for (uint256 i = 0; i < _amounts.length; i++) { - VELO.mint(_accounts[i], _amounts[i]); + FLOW.mint(_accounts[i], _amounts[i]); } } diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index 1fb8eeb9..d734521b 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -27,7 +27,7 @@ contract ExternalBribesTest is BaseTest { mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); deployPairFactoryAndRouter(); // deployVoter() @@ -45,12 +45,12 @@ contract ExternalBribesTest is BaseTest { distributor = new RewardsDistributor(address(escrow)); minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); address[] memory tokens = new address[](5); tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); tokens[4] = address(LR); voter.initialize(tokens, address(minter)); @@ -63,10 +63,10 @@ contract ExternalBribesTest is BaseTest { xbribe = ExternalBribe(gauge.external_bribe()); // ve - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.startPrank(address(owner2)); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.warp(block.timestamp + 1); vm.stopPrank(); diff --git a/test/Imbalance.t.sol b/test/Imbalance.t.sol index cc95424f..7ee86f22 100644 --- a/test/Imbalance.t.sol +++ b/test/Imbalance.t.sol @@ -19,26 +19,26 @@ contract ImbalanceTest is BaseTest { amounts[0] = 1e25; mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); } function createLock() public { deployBaseCoins(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.warp(1); assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); } function votingEscrowMerge() public { createLock(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); assertGt(escrow.balanceOfNFT(2), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), 2 * TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), 2 * TOKEN_1); escrow.merge(2, 1); assertGt(escrow.balanceOfNFT(1), 1990039602248405587); assertEq(escrow.balanceOfNFT(2), 0); @@ -89,7 +89,7 @@ contract ImbalanceTest is BaseTest { tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); voter.initialize(tokens, address(owner)); assertEq(voter.length(), 0); @@ -97,7 +97,7 @@ contract ImbalanceTest is BaseTest { function deployPairFactoryGauge() public { routerAddLiquidity(); - VELO.approve(address(gaugeFactory), 5 * TOKEN_100K); + FLOW.approve(address(gaugeFactory), 5 * TOKEN_100K); voter.createGauge(address(pair3)); assertFalse(voter.gauges(address(pair3)) == address(0)); diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index 5eeee2a7..d9cdb039 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -25,9 +25,9 @@ contract KillGaugesTest is BaseTest { amounts[2] = 1e25; mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); - VELO.approve(address(escrow), 100 * TOKEN_1); + FLOW.approve(address(escrow), 100 * TOKEN_1); escrow.create_lock(100 * TOKEN_1, 4 * 365 * 86400); vm.roll(block.number + 1); @@ -53,20 +53,20 @@ contract KillGaugesTest is BaseTest { minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); address[] memory tokens = new address[](4); tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); voter.initialize(tokens, address(minter)); - VELO.approve(address(gaugeFactory), 15 * TOKEN_100K); + FLOW.approve(address(gaugeFactory), 15 * TOKEN_100K); voter.createGauge(address(pair)); voter.createGauge(address(pair2)); - staking = new TestStakingRewards(address(pair), address(VELO)); - staking2 = new TestStakingRewards(address(pair2), address(VELO)); + staking = new TestStakingRewards(address(pair), address(FLOW)); + staking2 = new TestStakingRewards(address(pair2), address(FLOW)); address gaugeAddress = voter.gauges(address(pair)); gauge = Gauge(gaugeAddress); @@ -132,7 +132,7 @@ contract KillGaugesTest is BaseTest { minter.update_period(); voter.updateGauge(address(gauge)); uint256 claimable = voter.claimable(address(gauge)); - VELO.approve(address(staking), claimable); + FLOW.approve(address(staking), claimable); staking.notifyRewardAmount(claimable); address[] memory gauges = new address[](1); gauges[0] = address(gauge); @@ -150,7 +150,7 @@ contract KillGaugesTest is BaseTest { minter.update_period(); voter.updateGauge(address(gauge)); uint256 claimable = voter.claimable(address(gauge)); - VELO.approve(address(staking), claimable); + FLOW.approve(address(staking), claimable); staking.notifyRewardAmount(claimable); address[] memory gauges = new address[](1); gauges[0] = address(gauge); @@ -170,11 +170,11 @@ contract KillGaugesTest is BaseTest { uint256 claimable = voter.claimable(address(gauge)); console2.log(claimable); - VELO.approve(address(staking), claimable); + FLOW.approve(address(staking), claimable); staking.notifyRewardAmount(claimable); uint256 claimable2 = voter.claimable(address(gauge2)); - VELO.approve(address(staking), claimable2); + FLOW.approve(address(staking), claimable2); staking.notifyRewardAmount(claimable2); address[] memory gauges = new address[](2); diff --git a/test/LPRewards.t.sol b/test/LPRewards.t.sol index 9566dd20..2e10af9e 100644 --- a/test/LPRewards.t.sol +++ b/test/LPRewards.t.sol @@ -20,10 +20,10 @@ contract LPRewardsTest is BaseTest { amounts[1] = TOKEN_1M; mintFlow(owners, amounts); - // give owner1 veVELO + // give owner1 veFLOW VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); - VELO.approve(address(escrow), TOKEN_1M); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); + FLOW.approve(address(escrow), TOKEN_1M); escrow.create_lock(TOKEN_1M, 4 * 365 * 86400); deployPairFactoryAndRouter(); @@ -40,7 +40,7 @@ contract LPRewardsTest is BaseTest { tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); voter.initialize(tokens, address(owner)); escrow.setVoter(address(voter)); } @@ -72,7 +72,7 @@ contract LPRewardsTest is BaseTest { vm.roll(block.number + 1); address[] memory rewards = new address[](1); - rewards[0] = address(VELO); + rewards[0] = address(FLOW); // check derived balance is the same assertEq(gauge.derivedBalance(address(owner)), gauge.derivedBalance(address(owner2))); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 35dd3b02..36ef3ca4 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -23,7 +23,7 @@ contract MinterTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); @@ -36,28 +36,28 @@ contract MinterTest is BaseTest { address[] memory tokens = new address[](2); tokens[0] = address(FRAX); - tokens[1] = address(VELO); + tokens[1] = address(FLOW); voter.initialize(tokens, address(owner)); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); distributor = new RewardsDistributor(address(escrow)); escrow.setVoter(address(voter)); minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); - VELO.approve(address(router), TOKEN_1); + FLOW.approve(address(router), TOKEN_1); FRAX.approve(address(router), TOKEN_1); - router.addLiquidity(address(FRAX), address(VELO), false, TOKEN_1, TOKEN_1, 0, 0, address(owner), block.timestamp); + router.addLiquidity(address(FRAX), address(FLOW), false, TOKEN_1, TOKEN_1, 0, 0, address(owner), block.timestamp); - address pair = router.pairFor(address(FRAX), address(VELO), false); + address pair = router.pairFor(address(FRAX), address(FLOW), false); - VELO.approve(address(voter), 5 * TOKEN_100K); + FLOW.approve(address(voter), 5 * TOKEN_100K); voter.createGauge(pair); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); address[] memory pools = new address[](1); pools[0] = pair; @@ -77,7 +77,7 @@ contract MinterTest is BaseTest { assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); - assertEq(VELO.balanceOf(address(minter)), 19 * TOKEN_1M); + assertEq(FLOW.balanceOf(address(minter)), 19 * TOKEN_1M); } function testMinterWeeklyDistribute() public { @@ -101,7 +101,7 @@ contract MinterTest is BaseTest { uint256 weekly = minter.weekly(); console2.log(weekly); console2.log(minter.calculate_growth(weekly)); - console2.log(VELO.totalSupply()); + console2.log(FLOW.totalSupply()); console2.log(escrow.totalSupply()); vm.warp(block.timestamp + 86400 * 7); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index 0eb1b940..fe0e2be5 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -42,9 +42,9 @@ contract MinterTeamEmissions is BaseTest { factory.setVoter(address(voter)); address[] memory tokens = new address[](2); tokens[0] = address(FRAX); - tokens[1] = address(VELO); + tokens[1] = address(FLOW); voter.initialize(tokens, address(owner)); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); distributor = new RewardsDistributor(address(escrow)); escrow.setVoter(address(voter)); @@ -55,13 +55,13 @@ contract MinterTeamEmissions is BaseTest { address(distributor) ); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); - VELO.approve(address(router), TOKEN_1); + FLOW.approve(address(router), TOKEN_1); FRAX.approve(address(router), TOKEN_1); router.addLiquidity( address(FRAX), - address(VELO), + address(FLOW), false, TOKEN_1, TOKEN_1, @@ -71,13 +71,13 @@ contract MinterTeamEmissions is BaseTest { block.timestamp ); - address pair = router.pairFor(address(FRAX), address(VELO), false); + address pair = router.pairFor(address(FRAX), address(FLOW), false); - VELO.approve(address(voter), 5 * TOKEN_100K); + FLOW.approve(address(voter), 5 * TOKEN_100K); voter.createGauge(pair); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); address[] memory pools = new address[](1); pools[0] = pair; @@ -93,18 +93,18 @@ contract MinterTeamEmissions is BaseTest { assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); - assertEq(VELO.balanceOf(address(minter)), 14 * TOKEN_1M); + assertEq(FLOW.balanceOf(address(minter)), 14 * TOKEN_1M); - uint256 before = VELO.balanceOf(address(owner)); + uint256 before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 1 - uint256 after_ = VELO.balanceOf(address(owner)); + uint256 after_ = FLOW.balanceOf(address(owner)); assertEq(minter.weekly(), 15 * TOKEN_1M); assertEq(after_ - before, 0); vm.warp(block.timestamp + 86400 * 7); vm.roll(block.number + 1); - before = VELO.balanceOf(address(owner)); + before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 2 - after_ = VELO.balanceOf(address(owner)); + after_ = FLOW.balanceOf(address(owner)); assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift } @@ -131,33 +131,33 @@ contract MinterTeamEmissions is BaseTest { vm.warp(block.timestamp + 86400 * 7); vm.roll(block.number + 1); - uint256 beforeTeamSupply = VELO.balanceOf(address(team)); + uint256 beforeTeamSupply = FLOW.balanceOf(address(team)); uint256 weekly = minter.weekly_emission(); uint256 growth = minter.calculate_growth(weekly); minter.update_period(); // new period - uint256 afterTeamSupply = VELO.balanceOf(address(team)); + uint256 afterTeamSupply = FLOW.balanceOf(address(team)); uint256 newTeamVelo = afterTeamSupply - beforeTeamSupply; assertEq(((weekly + growth + newTeamVelo) * 30) / 1000, newTeamVelo); // check 3% of new emissions to team vm.warp(block.timestamp + 86400 * 7); vm.roll(block.number + 1); - beforeTeamSupply = VELO.balanceOf(address(team)); + beforeTeamSupply = FLOW.balanceOf(address(team)); weekly = minter.weekly_emission(); growth = minter.calculate_growth(weekly); minter.update_period(); // new period - afterTeamSupply = VELO.balanceOf(address(team)); + afterTeamSupply = FLOW.balanceOf(address(team)); newTeamVelo = afterTeamSupply - beforeTeamSupply; assertEq(((weekly + growth + newTeamVelo) * 30) / 1000, newTeamVelo); // check 3% of new emissions to team - // rate is right even when VELO is sent to Minter contract + // rate is right even when FLOW is sent to Minter contract vm.warp(block.timestamp + 86400 * 7); vm.roll(block.number + 1); - owner2.transfer(address(VELO), address(minter), 1e25); - beforeTeamSupply = VELO.balanceOf(address(team)); + owner2.transfer(address(FLOW), address(minter), 1e25); + beforeTeamSupply = FLOW.balanceOf(address(team)); weekly = minter.weekly_emission(); growth = minter.calculate_growth(weekly); minter.update_period(); // new period - afterTeamSupply = VELO.balanceOf(address(team)); + afterTeamSupply = FLOW.balanceOf(address(team)); newTeamVelo = afterTeamSupply - beforeTeamSupply; assertEq(((weekly + growth + newTeamVelo) * 30) / 1000, newTeamVelo); // check 3% of new emissions to team } @@ -179,11 +179,11 @@ contract MinterTeamEmissions is BaseTest { vm.warp(block.timestamp + 86400 * 7); vm.roll(block.number + 1); - uint256 beforeTeamSupply = VELO.balanceOf(address(team)); + uint256 beforeTeamSupply = FLOW.balanceOf(address(team)); uint256 weekly = minter.weekly_emission(); uint256 growth = minter.calculate_growth(weekly); minter.update_period(); // new period - uint256 afterTeamSupply = VELO.balanceOf(address(team)); + uint256 afterTeamSupply = FLOW.balanceOf(address(team)); uint256 newTeamVelo = afterTeamSupply - beforeTeamSupply; assertEq(((weekly + growth + newTeamVelo) * 50) / 1000, newTeamVelo); // check 5% of new emissions to team } diff --git a/test/NFTVote.t.sol b/test/NFTVote.t.sol index df380ef2..91a7f81a 100644 --- a/test/NFTVote.t.sol +++ b/test/NFTVote.t.sol @@ -20,22 +20,23 @@ contract NFTVoteTest is BaseTest { function setUp() public { deployOwners(); deployCoins(); + deployOwners(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); gov = new TestL2Governance(escrow); // test variable to vote on flag = new FlagCondition(); flag.transferOwnership(address(gov)); - VELO.mint(address(this), 1e21); + FLOW.mint(address(this), 1e21); vm.roll(block.number + 1); } function testLockAndPropose() public { uint256 fourYears = 4 * 365 * 24 * 3600; - VELO.approve(address(escrow), 1e21); + FLOW.approve(address(escrow), 1e21); escrow.create_lock(1e21, fourYears); uint256 quorum = gov.quorum(block.timestamp); uint256 numVotes = gov.getVotes(address(this), block.timestamp); diff --git a/test/Oracle.t.sol b/test/Oracle.t.sol index 5e554e50..4e87b6a1 100644 --- a/test/Oracle.t.sol +++ b/test/Oracle.t.sol @@ -13,7 +13,7 @@ contract OracleTest is BaseTest { uint256[] memory amounts = new uint256[](1); amounts[0] = 1e25; mintFlow(owners, amounts); - escrow = VotingEscrow(address(VELO)); + escrow = VotingEscrow(address(FLOW)); } function confirmTokensForFraxUsdc() public { diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 51bbb888..bded0cff 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -31,28 +31,28 @@ contract PairTest is BaseTest { mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); } function createLock() public { deployPairCoins(); - VELO.approve(address(escrow), 5e17); + FLOW.approve(address(escrow), 5e17); escrow.create_lock(5e17, 4 * 365 * 86400); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 495063075414519385); - assertEq(VELO.balanceOf(address(escrow)), 5e17); + assertEq(FLOW.balanceOf(address(escrow)), 5e17); } function increaseLock() public { createLock(); - VELO.approve(address(escrow), 5e17); + FLOW.approve(address(escrow), 5e17); escrow.increase_amount(1, 5e17); vm.expectRevert(abi.encodePacked('Can only increase lock duration')); escrow.increase_unlock_time(1, 4 * 365 * 86400); assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); } function votingEscrowViews() public { @@ -63,7 +63,7 @@ contract PairTest is BaseTest { assertEq(escrow.totalSupplyAt(block_), escrow.totalSupply()); assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); } function stealNFT() public { @@ -80,10 +80,10 @@ contract PairTest is BaseTest { function votingEscrowMerge() public { stealNFT(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); assertGt(escrow.balanceOfNFT(2), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), 2 * TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), 2 * TOKEN_1); console2.log(escrow.totalSupply()); escrow.merge(2, 1); console2.log(escrow.totalSupply()); @@ -92,10 +92,10 @@ contract PairTest is BaseTest { (int256 id, uint256 amount) = escrow.locked(2); assertEq(amount, 0); assertEq(escrow.ownerOf(2), address(0)); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); assertGt(escrow.balanceOfNFT(3), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), 3 * TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), 3 * TOKEN_1); console2.log(escrow.totalSupply()); escrow.merge(3, 1); console2.log(escrow.totalSupply()); @@ -262,12 +262,12 @@ contract PairTest is BaseTest { minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); address[] memory tokens = new address[](5); tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); tokens[4] = address(LR); voter.initialize(tokens, address(minter)); } @@ -275,13 +275,13 @@ contract PairTest is BaseTest { function deployPairFactoryGauge() public { deployMinter(); - VELO.approve(address(gaugeFactory), 15 * TOKEN_100K); + FLOW.approve(address(gaugeFactory), 15 * TOKEN_100K); voter.createGauge(address(pair)); voter.createGauge(address(pair2)); voter.createGauge(address(pair3)); assertFalse(voter.gauges(address(pair)) == address(0)); - staking = new TestStakingRewards(address(pair), address(VELO)); + staking = new TestStakingRewards(address(pair), address(FLOW)); address gaugeAddress = voter.gauges(address(pair)); address xBribeAddress = voter.external_bribes(gaugeAddress); @@ -354,17 +354,17 @@ contract PairTest is BaseTest { function addGaugeAndBribeRewards() public { withdrawGaugeStake(); - VELO.approve(address(gauge), PAIR_1); - VELO.approve(address(xbribe), PAIR_1); - VELO.approve(address(staking), PAIR_1); + FLOW.approve(address(gauge), PAIR_1); + FLOW.approve(address(xbribe), PAIR_1); + FLOW.approve(address(staking), PAIR_1); - gauge.notifyRewardAmount(address(VELO), PAIR_1); - xbribe.notifyRewardAmount(address(VELO), PAIR_1); + gauge.notifyRewardAmount(address(FLOW), PAIR_1); + xbribe.notifyRewardAmount(address(FLOW), PAIR_1); staking.notifyRewardAmount(PAIR_1); - assertEq(gauge.rewardRate(address(VELO)), 1653); + assertEq(gauge.rewardRate(address(FLOW)), 1653); // no reward rate, all or nothing - // assertEq(xbribe.rewardRate(address(VELO)), 1653); + // assertEq(xbribe.rewardRate(address(FLOW)), 1653); assertEq(staking.rewardRate(), 1653); } @@ -399,11 +399,11 @@ contract PairTest is BaseTest { function createLock2() public { voterPokeSelf(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.warp(block.timestamp + 1); assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), 4 * TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), 4 * TOKEN_1); } function voteHacking() public { @@ -495,7 +495,7 @@ contract PairTest is BaseTest { function gaugeDistributeBasedOnVoting() public { gaugePokeHacking3(); - VELO.approve(address(voter), PAIR_1); + FLOW.approve(address(voter), PAIR_1); voter.notifyRewardAmount(PAIR_1); voter.updateAll(); voter.distro(); @@ -505,7 +505,7 @@ contract PairTest is BaseTest { gaugeDistributeBasedOnVoting(); address[] memory rewards = new address[](1); - rewards[0] = address(VELO); + rewards[0] = address(FLOW); xbribe.getReward(1, rewards); vm.warp(block.timestamp + 691200); vm.roll(block.number + 1); @@ -598,10 +598,10 @@ contract PairTest is BaseTest { minter.initialize(claimants, amounts, TOKEN_1); minter.update_period(); voter.updateGauge(address(gauge)); - console2.log(VELO.balanceOf(address(distributor))); + console2.log(FLOW.balanceOf(address(distributor))); console2.log(distributor.claimable(1)); uint256 claimable = voter.claimable(address(gauge)); - VELO.approve(address(staking), claimable); + FLOW.approve(address(staking), claimable); staking.notifyRewardAmount(claimable); voter.distro(); vm.warp(block.timestamp + 1800); @@ -621,25 +621,25 @@ contract PairTest is BaseTest { gauge.deposit(PAIR_1, 0); staking.getReward(); vm.warp(block.timestamp + 1); - uint256 before = VELO.balanceOf(address(owner)); + uint256 before = FLOW.balanceOf(address(owner)); vm.warp(block.timestamp + 1); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); vm.warp(block.timestamp + 1); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); vm.warp(block.timestamp + 1); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); vm.warp(block.timestamp + 1); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); vm.warp(block.timestamp + 1); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); vm.warp(block.timestamp + 1); - uint256 earned = gauge.earned(address(VELO), address(owner)); + uint256 earned = gauge.earned(address(FLOW), address(owner)); address[] memory rewards = new address[](1); - rewards[0] = address(VELO); + rewards[0] = address(FLOW); vm.warp(block.timestamp + 1); gauge.getReward(address(owner), rewards); vm.warp(block.timestamp + 1); - uint256 after_ = VELO.balanceOf(address(owner)); + uint256 after_ = FLOW.balanceOf(address(owner)); uint256 received = after_ - before; gauge.withdraw(gauge.balanceOf(address(owner))); @@ -676,7 +676,7 @@ contract PairTest is BaseTest { gaugeClaimRewards(); address[] memory rewards = new address[](1); - rewards[0] = address(VELO); + rewards[0] = address(FLOW); pair.approve(address(gauge), PAIR_1); gauge.deposit(PAIR_1, 1); gauge.getReward(address(owner), rewards); @@ -755,16 +755,16 @@ contract PairTest is BaseTest { owner3.approve(address(pair), address(gauge), PAIR_1); owner3.deposit(address(gauge), PAIR_1, 0); owner3.withdrawGauge(address(gauge), gauge.balanceOf(address(owner3))); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); owner3.approve(address(pair), address(gauge), PAIR_1); owner3.deposit(address(gauge), PAIR_1, 0); - gauge.batchRewardPerToken(address(VELO), 200); - gauge.batchRewardPerToken(address(VELO), 200); - gauge.batchRewardPerToken(address(VELO), 200); - gauge.batchRewardPerToken(address(VELO), 200); + gauge.batchRewardPerToken(address(FLOW), 200); + gauge.batchRewardPerToken(address(FLOW), 200); + gauge.batchRewardPerToken(address(FLOW), 200); + gauge.batchRewardPerToken(address(FLOW), 200); address[] memory rewards = new address[](1); - rewards[0] = address(VELO); + rewards[0] = address(FLOW); owner3.getGaugeReward(address(gauge), address(owner3), rewards); owner3.withdrawGauge(address(gauge), gauge.balanceOf(address(owner3))); owner3.approve(address(pair), address(gauge), PAIR_1); @@ -792,7 +792,7 @@ contract PairTest is BaseTest { minter.update_period(); voter.updateGauge(address(gauge)); uint256 claimable = voter.claimable(address(gauge)); - VELO.approve(address(staking), claimable); + FLOW.approve(address(staking), claimable); staking.notifyRewardAmount(claimable); address[] memory gauges = new address[](1); gauges[0] = address(gauge); @@ -800,30 +800,30 @@ contract PairTest is BaseTest { voter.distro(); address[][] memory tokens = new address[][](1); address[] memory token = new address[](1); - token[0] = address(VELO); + token[0] = address(FLOW); tokens[0] = token; voter.claimRewards(gauges, tokens); - assertEq(gauge.rewardRate(address(VELO)), staking.rewardRate()); - console2.log(gauge.rewardPerTokenStored(address(VELO))); + assertEq(gauge.rewardRate(address(FLOW)), staking.rewardRate()); + console2.log(gauge.rewardPerTokenStored(address(FLOW))); } function gaugeClaimRewardsOwner3NextCycle() public { minterMint2(); owner3.withdrawGauge(address(gauge), gauge.balanceOf(address(owner3))); - console2.log(gauge.rewardPerTokenStored(address(VELO))); + console2.log(gauge.rewardPerTokenStored(address(FLOW))); owner3.approve(address(pair), address(gauge), PAIR_1); owner3.deposit(address(gauge), PAIR_1, 0); - uint256 before = VELO.balanceOf(address(owner3)); + uint256 before = FLOW.balanceOf(address(owner3)); vm.warp(block.timestamp + 1); - // uint256 earned = gauge.earned(address(VELO), address(owner3)); + // uint256 earned = gauge.earned(address(FLOW), address(owner3)); address[] memory rewards = new address[](1); - rewards[0] = address(VELO); + rewards[0] = address(FLOW); owner3.getGaugeReward(address(gauge), address(owner3), rewards); - uint256 after_ = VELO.balanceOf(address(owner3)); + uint256 after_ = FLOW.balanceOf(address(owner3)); uint256 received = after_ - before; assertGt(received, 0); - console2.log(gauge.rewardPerTokenStored(address(VELO))); + console2.log(gauge.rewardPerTokenStored(address(FLOW))); owner3.withdrawGauge(address(gauge), gauge.balanceOf(address(owner))); owner3.approve(address(pair), address(gauge), PAIR_1); @@ -857,8 +857,8 @@ contract PairTest is BaseTest { pair.approve(address(gauge), PAIR_1); gauge.deposit(PAIR_1, 0); - VELO.approve(address(gauge), VELO.balanceOf(address(owner))); - gauge.notifyRewardAmount(address(VELO), VELO.balanceOf(address(owner))); + FLOW.approve(address(gauge), FLOW.balanceOf(address(owner))); + gauge.notifyRewardAmount(address(FLOW), FLOW.balanceOf(address(owner))); vm.warp(block.timestamp + 604800); vm.roll(block.number + 1); diff --git a/test/Staking.t.sol b/test/Staking.t.sol index 63339835..e6fb57c3 100644 --- a/test/Staking.t.sol +++ b/test/Staking.t.sol @@ -21,28 +21,28 @@ contract StakingTest is BaseTest { mintFlow(owners, amounts); mintLR(owners, amounts); mintStake(owners, amounts); - escrow = new TestVotingEscrow(address(VELO)); + escrow = new TestVotingEscrow(address(FLOW)); voter = new TestVoter(); } function createLock() public { deployBaseCoins(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); } function createLock2() public { createLock(); - owner2.approve(address(VELO), address(escrow), TOKEN_1); + owner2.approve(address(FLOW), address(escrow), TOKEN_1); owner2.create_lock(address(escrow), TOKEN_1, 4 * 365 * 86400); } function createLock3() public { createLock2(); - owner3.approve(address(VELO), address(escrow), TOKEN_1); + owner3.approve(address(FLOW), address(escrow), TOKEN_1); owner3.create_lock(address(escrow), TOKEN_1, 4 * 365 * 86400); } @@ -56,7 +56,7 @@ contract StakingTest is BaseTest { address gaugeAddr = gaugeFactory.last_gauge(); gauge = Gauge(gaugeAddr); - staking = new TestStakingRewards(address(stake), address(VELO)); + staking = new TestStakingRewards(address(stake), address(FLOW)); } function depositEmpty() public { @@ -67,7 +67,7 @@ contract StakingTest is BaseTest { staking.stake(1e21); gauge.deposit(1e21, 1); - assertEq(gauge.earned(address(VELO), address(owner)), staking.earned(address(owner))); + assertEq(gauge.earned(address(FLOW), address(owner)), staking.earned(address(owner))); } function depositEmpty2() public { @@ -78,7 +78,7 @@ contract StakingTest is BaseTest { owner2.stakeStake(address(staking), 1e21); owner2.deposit(address(gauge), 1e21, 2); - assertEq(gauge.earned(address(VELO), address(owner2)), staking.earned(address(owner2))); + assertEq(gauge.earned(address(FLOW), address(owner2)), staking.earned(address(owner2))); } function depositEmpty3() public { @@ -89,27 +89,27 @@ contract StakingTest is BaseTest { owner3.stakeStake(address(staking), 1e21); owner3.deposit(address(gauge), 1e21, 3); - assertEq(gauge.earned(address(VELO), address(owner3)), staking.earned(address(owner3))); + assertEq(gauge.earned(address(FLOW), address(owner3)), staking.earned(address(owner3))); } function notifyRewardsAndCompare() public { depositEmpty3(); - VELO.approve(address(staking), TOKEN_1M); - VELO.approve(address(gauge), TOKEN_1M); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + FLOW.approve(address(staking), TOKEN_1M); + FLOW.approve(address(gauge), TOKEN_1M); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.notifyRewardAmount(TOKEN_1M); - gauge.notifyRewardAmount(address(VELO), TOKEN_1M); + gauge.notifyRewardAmount(address(FLOW), TOKEN_1M); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); - VELO.approve(address(staking), TOKEN_1M); - VELO.approve(address(gauge), TOKEN_1M); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); + FLOW.approve(address(staking), TOKEN_1M); + FLOW.approve(address(gauge), TOKEN_1M); staking.notifyRewardAmount(TOKEN_1M); - gauge.notifyRewardAmount(address(VELO), TOKEN_1M); + gauge.notifyRewardAmount(address(FLOW), TOKEN_1M); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); } function notifyReward2AndCompare() public { @@ -133,38 +133,38 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); staking.withdraw(1e21); @@ -173,8 +173,8 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); vm.warp(block.timestamp + 604800); vm.roll(block.number + 1); staking.withdraw(1e21); @@ -183,8 +183,8 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); } function notifyRewardsAndCompareOwner2() public { @@ -278,32 +278,32 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); staking.withdraw(1e21); @@ -312,8 +312,8 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); vm.warp(block.timestamp + 604800); vm.roll(block.number + 1); staking.withdraw(1e21); @@ -322,29 +322,29 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); } function notifyRewardsAndCompareSet2() public { depositAndWithdrawWithoutRewards(); - VELO.approve(address(staking), TOKEN_1M); - VELO.approve(address(gauge), TOKEN_1M); + FLOW.approve(address(staking), TOKEN_1M); + FLOW.approve(address(gauge), TOKEN_1M); staking.notifyRewardAmount(TOKEN_1M); - gauge.notifyRewardAmount(address(VELO), TOKEN_1M); + gauge.notifyRewardAmount(address(FLOW), TOKEN_1M); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); - VELO.approve(address(staking), TOKEN_1M); - VELO.approve(address(gauge), TOKEN_1M); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); + FLOW.approve(address(staking), TOKEN_1M); + FLOW.approve(address(gauge), TOKEN_1M); staking.notifyRewardAmount(TOKEN_1M); - gauge.notifyRewardAmount(address(VELO), TOKEN_1M); + gauge.notifyRewardAmount(address(FLOW), TOKEN_1M); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); assertEq(gauge.derivedSupply(), staking.totalSupply()); } @@ -370,32 +370,32 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); staking.withdraw(1e21); gauge.withdraw(1e21); stake.approve(address(staking), 1e21); stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); vm.warp(block.timestamp + 1800); vm.roll(block.number + 1); staking.withdraw(1e21); @@ -404,16 +404,16 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); - // uint256 sb = VELO.balanceOf(address(owner)); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); + // uint256 sb = FLOW.balanceOf(address(owner)); staking.getReward(); - // uint256 sa = VELO.balanceOf(address(owner)); - // uint256 gb = VELO.balanceOf(address(owner)); + // uint256 sa = FLOW.balanceOf(address(owner)); + // uint256 gb = FLOW.balanceOf(address(owner)); address[] memory tokens = new address[](1); - tokens[0] = address(VELO); + tokens[0] = address(FLOW); gauge.getReward(address(owner), tokens); - // uint256 ga = VELO.balanceOf(address(owner)); + // uint256 ga = FLOW.balanceOf(address(owner)); vm.warp(block.timestamp + 604800); vm.roll(block.number + 1); staking.withdraw(1e21); @@ -422,8 +422,8 @@ contract StakingTest is BaseTest { stake.approve(address(gauge), 1e21); staking.stake(1e21); gauge.deposit(1e21, 1); - gauge.batchRewardPerToken(address(VELO), 200); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + gauge.batchRewardPerToken(address(FLOW), 200); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); assertGt(staking.rewardPerTokenStored(), 1330355346300364281191); } @@ -464,7 +464,7 @@ contract StakingTest is BaseTest { owner2.deposit(address(gauge), 1e21, 2); owner2.getStakeReward(address(staking)); address[] memory tokens = new address[](1); - tokens[0] = address(VELO); + tokens[0] = address(FLOW); owner2.getGaugeReward(address(gauge), address(owner2), tokens); vm.warp(block.timestamp + 604800); vm.roll(block.number + 1); @@ -474,7 +474,7 @@ contract StakingTest is BaseTest { owner2.approve(address(stake), address(gauge), 1e21); owner2.stakeStake(address(staking), 1e21); owner2.deposit(address(gauge), 1e21, 2); - assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(VELO))); + assertEq(staking.rewardPerTokenStored(), gauge.rewardPerTokenStored(address(FLOW))); assertGt(staking.rewardPerTokenStored(), 1330355346300364281191); } diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol index 11362057..0ae8495a 100644 --- a/test/VeloGovernor.t.sol +++ b/test/VeloGovernor.t.sol @@ -25,15 +25,15 @@ contract VeloGovernorTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); - VELO.approve(address(escrow), 97 * TOKEN_1); + FLOW.approve(address(escrow), 97 * TOKEN_1); escrow.create_lock(97 * TOKEN_1, 4 * 365 * 86400); vm.roll(block.number + 1); // owner2 owns less than quorum, 3% vm.startPrank(address(owner2)); - VELO.approve(address(escrow), 3 * TOKEN_1); + FLOW.approve(address(escrow), 3 * TOKEN_1); escrow.create_lock(3 * TOKEN_1, 4 * 365 * 86400); vm.roll(block.number + 1); vm.stopPrank(); @@ -57,12 +57,12 @@ contract VeloGovernorTest is BaseTest { minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); address address1 = factory.getPair(address(FRAX), address(USDC), true); pair = Pair(address1); - VELO.approve(address(gaugeFactory), 15 * TOKEN_100K); + FLOW.approve(address(gaugeFactory), 15 * TOKEN_100K); voter.createGauge(address(pair)); address gaugeAddress = voter.gauges(address(pair)); gauge = Gauge(gaugeAddress); @@ -96,7 +96,7 @@ contract VeloGovernorTest is BaseTest { function testVeVeloMergesAutoDelegates() public { // owner2 + owner3 > quorum vm.startPrank(address(owner3)); - VELO.approve(address(escrow), 3 * TOKEN_1); + FLOW.approve(address(escrow), 3 * TOKEN_1); escrow.create_lock(3 * TOKEN_1, 4 * 365 * 86400); vm.roll(block.number + 1); uint256 pre2 = escrow.getVotes(address(owner2)); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 2cc803ca..6cdd02ce 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -25,7 +25,7 @@ contract VeloVotingTest is BaseTest { mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); @@ -44,9 +44,9 @@ contract VeloVotingTest is BaseTest { address[] memory tokens = new address[](2); tokens[0] = address(FRAX); - tokens[1] = address(VELO); + tokens[1] = address(FLOW); voter.initialize(tokens, address(owner)); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); distributor = new RewardsDistributor(address(escrow)); escrow.setVoter(address(voter)); @@ -57,13 +57,13 @@ contract VeloVotingTest is BaseTest { address(distributor) ); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); - VELO.approve(address(router), TOKEN_1); + FLOW.approve(address(router), TOKEN_1); FRAX.approve(address(router), TOKEN_1); router.addLiquidity( address(FRAX), - address(VELO), + address(FLOW), false, TOKEN_1, TOKEN_1, @@ -73,13 +73,13 @@ contract VeloVotingTest is BaseTest { block.timestamp ); - address pair = router.pairFor(address(FRAX), address(VELO), false); + address pair = router.pairFor(address(FRAX), address(FLOW), false); - VELO.approve(address(voter), 5 * TOKEN_100K); + FLOW.approve(address(voter), 5 * TOKEN_100K); voter.createGauge(pair); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); address[] memory pools = new address[](1); pools[0] = pair; @@ -95,18 +95,18 @@ contract VeloVotingTest is BaseTest { assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); - assertEq(VELO.balanceOf(address(minter)), 14 * TOKEN_1M); + assertEq(FLOW.balanceOf(address(minter)), 14 * TOKEN_1M); - uint256 before = VELO.balanceOf(address(owner)); + uint256 before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 1 - uint256 after_ = VELO.balanceOf(address(owner)); + uint256 after_ = FLOW.balanceOf(address(owner)); assertEq(minter.weekly(), 15 * TOKEN_1M); assertEq(after_ - before, 0); vm.warp(block.timestamp + 86400 * 7); vm.roll(block.number + 1); - before = VELO.balanceOf(address(owner)); + before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 2 - after_ = VELO.balanceOf(address(owner)); + after_ = FLOW.balanceOf(address(owner)); assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift } diff --git a/test/VotingEscrow.t.sol b/test/VotingEscrow.t.sol index 62a4fbfb..8d12099c 100644 --- a/test/VotingEscrow.t.sol +++ b/test/VotingEscrow.t.sol @@ -15,11 +15,11 @@ contract VotingEscrowTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); } function testCreateLock() public { - VELO.approve(address(escrow), 1e21); + FLOW.approve(address(escrow), 1e21); uint256 lockDuration = 7 * 24 * 3600; // 1 week // Balance should be zero before and 1 after creating the lock @@ -30,7 +30,7 @@ contract VotingEscrowTest is BaseTest { } function testCreateLockOutsideAllowedZones() public { - VELO.approve(address(escrow), 1e21); + FLOW.approve(address(escrow), 1e21); uint256 oneWeek = 7 * 24 * 3600; uint256 fourYears = 4 * 365 * 24 * 3600; vm.expectRevert(abi.encodePacked('Voting lock can be 4 years max')); @@ -38,7 +38,7 @@ contract VotingEscrowTest is BaseTest { } function testWithdraw() public { - VELO.approve(address(escrow), 1e21); + FLOW.approve(address(escrow), 1e21); uint256 lockDuration = 7 * 24 * 3600; // 1 week escrow.create_lock(1e21, lockDuration); @@ -51,7 +51,7 @@ contract VotingEscrowTest is BaseTest { vm.roll(block.number + 1); // mine the next block escrow.withdraw(tokenId); - assertEq(VELO.balanceOf(address(owner)), 1e21); + assertEq(FLOW.balanceOf(address(owner)), 1e21); // Check that the NFT is burnt assertEq(escrow.balanceOfNFT(tokenId), 0); assertEq(escrow.ownerOf(tokenId), address(0)); @@ -61,7 +61,7 @@ contract VotingEscrowTest is BaseTest { // tokenURI should not work for non-existent token ids vm.expectRevert(abi.encodePacked("Query for nonexistent token")); escrow.tokenURI(999); - VELO.approve(address(escrow), 1e21); + FLOW.approve(address(escrow), 1e21); uint256 lockDuration = 7 * 24 * 3600; // 1 week escrow.create_lock(1e21, lockDuration); diff --git a/test/WashTrade.t.sol b/test/WashTrade.t.sol index 82ac79dd..fae767be 100644 --- a/test/WashTrade.t.sol +++ b/test/WashTrade.t.sol @@ -22,27 +22,27 @@ contract WashTradeTest is BaseTest { mintFlow(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); } function createLock() public { deployBaseCoins(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); } function votingEscrowMerge() public { createLock(); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.roll(block.number + 1); assertGt(escrow.balanceOfNFT(2), 995063075414519385); - assertEq(VELO.balanceOf(address(escrow)), 2 * TOKEN_1); + assertEq(FLOW.balanceOf(address(escrow)), 2 * TOKEN_1); escrow.merge(2, 1); assertGt(escrow.balanceOfNFT(1), 1990039602248405587); assertEq(escrow.balanceOfNFT(2), 0); @@ -93,7 +93,7 @@ contract WashTradeTest is BaseTest { tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); voter.initialize(tokens, address(owner)); assertEq(voter.length(), 0); @@ -102,7 +102,7 @@ contract WashTradeTest is BaseTest { function deployPairFactoryGauge() public { routerAddLiquidity(); - VELO.approve(address(gaugeFactory), 5 * TOKEN_100K); + FLOW.approve(address(gaugeFactory), 5 * TOKEN_100K); voter.createGauge(address(pair3)); assertFalse(voter.gauges(address(pair3)) == address(0)); diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index 2c50362c..fd35cc2d 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -29,7 +29,7 @@ contract WrappedExternalBribesTest is BaseTest { mintFlow(owners, amounts); mintLR(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); deployPairFactoryAndRouter(); // deployVoter() @@ -47,12 +47,12 @@ contract WrappedExternalBribesTest is BaseTest { distributor = new RewardsDistributor(address(escrow)); minter = new Minter(address(voter), address(escrow), address(distributor)); distributor.setDepositor(address(minter)); - VELO.setMinter(address(minter)); + FLOW.setMinter(address(minter)); address[] memory tokens = new address[](5); tokens[0] = address(USDC); tokens[1] = address(FRAX); tokens[2] = address(DAI); - tokens[3] = address(VELO); + tokens[3] = address(FLOW); tokens[4] = address(LR); voter.initialize(tokens, address(minter)); @@ -66,10 +66,10 @@ contract WrappedExternalBribesTest is BaseTest { wxbribe = WrappedExternalBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); // ve - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.startPrank(address(owner2)); - VELO.approve(address(escrow), TOKEN_1); + FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, 4 * 365 * 86400); vm.warp(block.timestamp + 1); vm.stopPrank(); From 7a7e5a37207987c17d99b29792610e501d11a298 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:00:24 +0000 Subject: [PATCH 055/156] fix: VELO -> FLOW --- test/MinterTeamEmissions.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index fe0e2be5..d9553130 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -25,7 +25,7 @@ contract MinterTeamEmissions is BaseTest { mintFlow(owners, amountsVelo); team = new TestOwner(); VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(VELO), address(artProxy), owners[0]); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); factory = new PairFactory(); router = new Router(address(factory), address(owner)); gaugeFactory = new GaugeFactory(); From 2abd63026d42f3619157bc2f8ac7d4fa13903d86 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:03:36 +0000 Subject: [PATCH 056/156] refactor: Rename VelodromeLibrary to VelocimeterLibrary --- contracts/{VelodromeLibrary.sol => VelocimeterLibrary.sol} | 4 ++-- tasks/deploy/op.ts | 4 ++-- test/BaseTest.sol | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) rename contracts/{VelodromeLibrary.sol => VelocimeterLibrary.sol} (99%) diff --git a/contracts/VelodromeLibrary.sol b/contracts/VelocimeterLibrary.sol similarity index 99% rename from contracts/VelodromeLibrary.sol rename to contracts/VelocimeterLibrary.sol index 9682faa5..2b38a774 100644 --- a/contracts/VelodromeLibrary.sol +++ b/contracts/VelocimeterLibrary.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.13; import "contracts/interfaces/IPair.sol"; import "contracts/interfaces/IRouter.sol"; -contract VelodromeLibrary { +contract VelocimeterLibrary { IRouter internal immutable router; constructor(address _router) { @@ -101,5 +101,5 @@ contract VelodromeLibrary { return x * y; // xy >= k } } - + } diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index 9e7993c3..4843d3fe 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -31,7 +31,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ethers.getContractFactory("BribeFactory"), ethers.getContractFactory("PairFactory"), ethers.getContractFactory("Router"), - ethers.getContractFactory("VelodromeLibrary"), + ethers.getContractFactory("VelocimeterLibrary"), ethers.getContractFactory("VeArtProxy"), ethers.getContractFactory("VotingEscrow"), ethers.getContractFactory("RewardsDistributor"), @@ -63,7 +63,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( const library = await Library.deploy(router.address); await library.deployed(); - console.log("VelodromeLibrary deployed to: ", library.address); + console.log("VelocimeterLibrary deployed to: ", library.address); console.log("Args: ", router.address, "\n"); const artProxy = await VeArtProxy.deploy(); diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 958ae273..76fece06 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -14,7 +14,7 @@ import "contracts/Pair.sol"; import "contracts/RewardsDistributor.sol"; import "contracts/Router.sol"; import "contracts/Flow.sol"; -import "contracts/VelodromeLibrary.sol"; +import "contracts/VelocimeterLibrary.sol"; import "contracts/Voter.sol"; import "contracts/VeArtProxy.sol"; import "contracts/VotingEscrow.sol"; @@ -49,7 +49,7 @@ abstract contract BaseTest is Test, TestOwner { TestToken stake; PairFactory factory; Router router; - VelodromeLibrary lib; + VelocimeterLibrary lib; Pair pair; Pair pair2; Pair pair3; @@ -123,7 +123,7 @@ abstract contract BaseTest is Test, TestOwner { router = new Router(address(factory), address(WETH)); assertEq(router.factory(), address(factory)); - lib = new VelodromeLibrary(address(router)); + lib = new VelocimeterLibrary(address(router)); } function deployPairWithOwner(address _owner) public { From 8ca58922fa80ffb1e00c3c87dafeb352c798ab8e Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:12:03 +0000 Subject: [PATCH 057/156] test: Extract 4 years as a constant --- test/BaseTest.sol | 1 + test/ExternalBribes.t.sol | 4 ++-- test/Imbalance.t.sol | 4 ++-- test/KillGauges.t.sol | 2 +- test/LPRewards.t.sol | 2 +- test/Minter.t.sol | 2 +- test/MinterTeamEmissions.t.sol | 2 +- test/Pair.t.sol | 12 ++++++------ test/Staking.t.sol | 6 +++--- test/VeloGovernor.t.sol | 8 ++++---- test/VeloVoting.t.sol | 2 +- test/WashTrade.t.sol | 4 ++-- test/WrappedExternalBribes.t.sol | 4 ++-- 13 files changed, 27 insertions(+), 26 deletions(-) diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 76fece06..9aa3966f 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -34,6 +34,7 @@ abstract contract BaseTest is Test, TestOwner { uint256 constant TOKEN_100M = 1e26; // 1e8 = 100M tokens with 18 decimals uint256 constant TOKEN_10B = 1e28; // 1e10 = 10B tokens with 18 decimals uint256 constant PAIR_1 = 1e9; + uint256 constant internal FOUR_YEARS = 4 * 365 * 86400; TestOwner owner; TestOwner owner2; diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index d734521b..6b54479a 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -64,10 +64,10 @@ contract ExternalBribesTest is BaseTest { // ve FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.startPrank(address(owner2)); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.warp(block.timestamp + 1); vm.stopPrank(); } diff --git a/test/Imbalance.t.sol b/test/Imbalance.t.sol index 7ee86f22..490a2d59 100644 --- a/test/Imbalance.t.sol +++ b/test/Imbalance.t.sol @@ -26,7 +26,7 @@ contract ImbalanceTest is BaseTest { deployBaseCoins(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.warp(1); assertGt(escrow.balanceOfNFT(1), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); @@ -36,7 +36,7 @@ contract ImbalanceTest is BaseTest { createLock(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); assertGt(escrow.balanceOfNFT(2), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), 2 * TOKEN_1); escrow.merge(2, 1); diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index d9cdb039..81388492 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -28,7 +28,7 @@ contract KillGaugesTest is BaseTest { escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); FLOW.approve(address(escrow), 100 * TOKEN_1); - escrow.create_lock(100 * TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(100 * TOKEN_1, FOUR_YEARS); vm.roll(block.number + 1); deployPairFactoryAndRouter(); diff --git a/test/LPRewards.t.sol b/test/LPRewards.t.sol index 2e10af9e..b5e8a71e 100644 --- a/test/LPRewards.t.sol +++ b/test/LPRewards.t.sol @@ -24,7 +24,7 @@ contract LPRewardsTest is BaseTest { VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); FLOW.approve(address(escrow), TOKEN_1M); - escrow.create_lock(TOKEN_1M, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1M, FOUR_YEARS); deployPairFactoryAndRouter(); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 36ef3ca4..518fd586 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -39,7 +39,7 @@ contract MinterTest is BaseTest { tokens[1] = address(FLOW); voter.initialize(tokens, address(owner)); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); distributor = new RewardsDistributor(address(escrow)); escrow.setVoter(address(voter)); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index d9553130..9941b9fd 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -45,7 +45,7 @@ contract MinterTeamEmissions is BaseTest { tokens[1] = address(FLOW); voter.initialize(tokens, address(owner)); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); distributor = new RewardsDistributor(address(escrow)); escrow.setVoter(address(voter)); diff --git a/test/Pair.t.sol b/test/Pair.t.sol index bded0cff..41e47ff2 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -38,7 +38,7 @@ contract PairTest is BaseTest { deployPairCoins(); FLOW.approve(address(escrow), 5e17); - escrow.create_lock(5e17, 4 * 365 * 86400); + escrow.create_lock(5e17, FOUR_YEARS); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 495063075414519385); assertEq(FLOW.balanceOf(address(escrow)), 5e17); @@ -50,7 +50,7 @@ contract PairTest is BaseTest { FLOW.approve(address(escrow), 5e17); escrow.increase_amount(1, 5e17); vm.expectRevert(abi.encodePacked('Can only increase lock duration')); - escrow.increase_unlock_time(1, 4 * 365 * 86400); + escrow.increase_unlock_time(1, FOUR_YEARS); assertGt(escrow.balanceOfNFT(1), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); } @@ -81,7 +81,7 @@ contract PairTest is BaseTest { stealNFT(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); assertGt(escrow.balanceOfNFT(2), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), 2 * TOKEN_1); console2.log(escrow.totalSupply()); @@ -93,7 +93,7 @@ contract PairTest is BaseTest { assertEq(amount, 0); assertEq(escrow.ownerOf(2), address(0)); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); assertGt(escrow.balanceOfNFT(3), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), 3 * TOKEN_1); console2.log(escrow.totalSupply()); @@ -400,7 +400,7 @@ contract PairTest is BaseTest { voterPokeSelf(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.warp(block.timestamp + 1); assertGt(escrow.balanceOfNFT(1), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), 4 * TOKEN_1); @@ -723,7 +723,7 @@ contract PairTest is BaseTest { voter.claimFees(bribes_, rewards, 1); uint256 supply = escrow.totalSupply(); assertGt(supply, 0); - vm.warp(block.timestamp + 4*365*86400); + vm.warp(block.timestamp + FOUR_YEARS); vm.roll(block.number + 1); assertEq(escrow.balanceOfNFT(1), 0); assertEq(escrow.totalSupply(), 0); diff --git a/test/Staking.t.sol b/test/Staking.t.sol index e6fb57c3..1e1fac88 100644 --- a/test/Staking.t.sol +++ b/test/Staking.t.sol @@ -29,21 +29,21 @@ contract StakingTest is BaseTest { deployBaseCoins(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); } function createLock2() public { createLock(); owner2.approve(address(FLOW), address(escrow), TOKEN_1); - owner2.create_lock(address(escrow), TOKEN_1, 4 * 365 * 86400); + owner2.create_lock(address(escrow), TOKEN_1, FOUR_YEARS); } function createLock3() public { createLock2(); owner3.approve(address(FLOW), address(escrow), TOKEN_1); - owner3.create_lock(address(escrow), TOKEN_1, 4 * 365 * 86400); + owner3.create_lock(address(escrow), TOKEN_1, FOUR_YEARS); } function deployFactory() public { diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol index 0ae8495a..9350e541 100644 --- a/test/VeloGovernor.t.sol +++ b/test/VeloGovernor.t.sol @@ -28,13 +28,13 @@ contract VeloGovernorTest is BaseTest { escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); FLOW.approve(address(escrow), 97 * TOKEN_1); - escrow.create_lock(97 * TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(97 * TOKEN_1, FOUR_YEARS); vm.roll(block.number + 1); // owner2 owns less than quorum, 3% vm.startPrank(address(owner2)); FLOW.approve(address(escrow), 3 * TOKEN_1); - escrow.create_lock(3 * TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(3 * TOKEN_1, FOUR_YEARS); vm.roll(block.number + 1); vm.stopPrank(); @@ -97,7 +97,7 @@ contract VeloGovernorTest is BaseTest { // owner2 + owner3 > quorum vm.startPrank(address(owner3)); FLOW.approve(address(escrow), 3 * TOKEN_1); - escrow.create_lock(3 * TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(3 * TOKEN_1, FOUR_YEARS); vm.roll(block.number + 1); uint256 pre2 = escrow.getVotes(address(owner2)); uint256 pre3 = escrow.getVotes(address(owner3)); @@ -115,7 +115,7 @@ contract VeloGovernorTest is BaseTest { assertApproxEqAbs( pre2 + pre3, post2, - 4 * 365 * 86400 // merge rounds down time lock + FOUR_YEARS // merge rounds down time lock ); } diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 6cdd02ce..0720cbfb 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -47,7 +47,7 @@ contract VeloVotingTest is BaseTest { tokens[1] = address(FLOW); voter.initialize(tokens, address(owner)); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); distributor = new RewardsDistributor(address(escrow)); escrow.setVoter(address(voter)); diff --git a/test/WashTrade.t.sol b/test/WashTrade.t.sol index fae767be..c0cc4fb4 100644 --- a/test/WashTrade.t.sol +++ b/test/WashTrade.t.sol @@ -29,7 +29,7 @@ contract WashTradeTest is BaseTest { deployBaseCoins(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block assertGt(escrow.balanceOfNFT(1), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), TOKEN_1); @@ -39,7 +39,7 @@ contract WashTradeTest is BaseTest { createLock(); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.roll(block.number + 1); assertGt(escrow.balanceOfNFT(2), 995063075414519385); assertEq(FLOW.balanceOf(address(escrow)), 2 * TOKEN_1); diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index fd35cc2d..d99d7093 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -67,10 +67,10 @@ contract WrappedExternalBribesTest is BaseTest { // ve FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.startPrank(address(owner2)); FLOW.approve(address(escrow), TOKEN_1); - escrow.create_lock(TOKEN_1, 4 * 365 * 86400); + escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.warp(block.timestamp + 1); vm.stopPrank(); } From 0c4a93c94bc3ca8e1edecb6f87a0356646ddd14c Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:13:27 +0000 Subject: [PATCH 058/156] test: Extract 1 week as a constant --- test/BaseTest.sol | 4 +++- test/KillGauges.t.sol | 6 +++--- test/Minter.t.sol | 14 +++++++------- test/MinterTeamEmissions.t.sol | 10 +++++----- test/Pair.t.sol | 2 +- test/VeloVoting.t.sol | 2 +- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 9aa3966f..45b0ca93 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -34,7 +34,9 @@ abstract contract BaseTest is Test, TestOwner { uint256 constant TOKEN_100M = 1e26; // 1e8 = 100M tokens with 18 decimals uint256 constant TOKEN_10B = 1e28; // 1e10 = 10B tokens with 18 decimals uint256 constant PAIR_1 = 1e9; - uint256 constant internal FOUR_YEARS = 4 * 365 * 86400; + uint256 constant private ONE_DAY = 86400; + uint256 constant internal ONE_WEEK = ONE_DAY * 7; + uint256 constant internal FOUR_YEARS = 4 * 365 * ONE_DAY; TestOwner owner; TestOwner owner2; diff --git a/test/KillGauges.t.sol b/test/KillGauges.t.sol index 81388492..4e17c64f 100644 --- a/test/KillGauges.t.sol +++ b/test/KillGauges.t.sol @@ -127,7 +127,7 @@ contract KillGaugesTest is BaseTest { } function testKilledGaugeCanUpdateButGoesToZero() public { - vm.warp(block.timestamp + 86400 * 7 * 2); + vm.warp(block.timestamp + ONE_WEEK * 2); vm.roll(block.number + 1); minter.update_period(); voter.updateGauge(address(gauge)); @@ -145,7 +145,7 @@ contract KillGaugesTest is BaseTest { } function testKilledGaugeCanDistributeButGoesToZero() public { - vm.warp(block.timestamp + 86400 * 7 * 2); + vm.warp(block.timestamp + ONE_WEEK * 2); vm.roll(block.number + 1); minter.update_period(); voter.updateGauge(address(gauge)); @@ -162,7 +162,7 @@ contract KillGaugesTest is BaseTest { } function testCanStillDistroAllWithKilledGauge() public { - vm.warp(block.timestamp + 86400 * 7 * 2); + vm.warp(block.timestamp + ONE_WEEK * 2); vm.roll(block.number + 1); minter.update_period(); voter.updateGauge(address(gauge)); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 518fd586..0095f12c 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -85,12 +85,12 @@ contract MinterTest is BaseTest { minter.update_period(); assertEq(minter.weekly(), 15 * TOKEN_1M); // 15M - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); assertEq(distributor.claimable(1), 0); assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); uint256 claimable = distributor.claimable(1); @@ -104,29 +104,29 @@ contract MinterTest is BaseTest { console2.log(FLOW.totalSupply()); console2.log(escrow.totalSupply()); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim(1); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); console2.log(distributor.claimable(1)); uint256[] memory tokenIds = new uint256[](1); tokenIds[0] = 1; distributor.claim_many(tokenIds); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim(1); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim_many(tokenIds); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); minter.update_period(); console2.log(distributor.claimable(1)); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index 9941b9fd..bff7a27f 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -100,7 +100,7 @@ contract MinterTeamEmissions is BaseTest { uint256 after_ = FLOW.balanceOf(address(owner)); assertEq(minter.weekly(), 15 * TOKEN_1M); assertEq(after_ - before, 0); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 2 @@ -129,7 +129,7 @@ contract MinterTeamEmissions is BaseTest { owner.setTeam(address(minter), address(team)); team.acceptTeam(address(minter)); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); uint256 beforeTeamSupply = FLOW.balanceOf(address(team)); uint256 weekly = minter.weekly_emission(); @@ -139,7 +139,7 @@ contract MinterTeamEmissions is BaseTest { uint256 newTeamVelo = afterTeamSupply - beforeTeamSupply; assertEq(((weekly + growth + newTeamVelo) * 30) / 1000, newTeamVelo); // check 3% of new emissions to team - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); beforeTeamSupply = FLOW.balanceOf(address(team)); weekly = minter.weekly_emission(); @@ -150,7 +150,7 @@ contract MinterTeamEmissions is BaseTest { assertEq(((weekly + growth + newTeamVelo) * 30) / 1000, newTeamVelo); // check 3% of new emissions to team // rate is right even when FLOW is sent to Minter contract - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); owner2.transfer(address(FLOW), address(minter), 1e25); beforeTeamSupply = FLOW.balanceOf(address(team)); @@ -177,7 +177,7 @@ contract MinterTeamEmissions is BaseTest { // new rate in bounds team.setTeamEmissions(address(minter), 50); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); uint256 beforeTeamSupply = FLOW.balanceOf(address(team)); uint256 weekly = minter.weekly_emission(); diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 41e47ff2..194bb332 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -787,7 +787,7 @@ contract PairTest is BaseTest { function minterMint2() public { gaugeClaimRewardsOwner3(); - vm.warp(block.timestamp + 86400 * 7 * 2); + vm.warp(block.timestamp + ONE_WEEK * 2); vm.roll(block.number + 1); minter.update_period(); voter.updateGauge(address(gauge)); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 0720cbfb..43fefd34 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -102,7 +102,7 @@ contract VeloVotingTest is BaseTest { uint256 after_ = FLOW.balanceOf(address(owner)); assertEq(minter.weekly(), 15 * TOKEN_1M); assertEq(after_ - before, 0); - vm.warp(block.timestamp + 86400 * 7); + vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 2 From 54459028ebc0f26bfd9afb97fd4525fcc2a0fa64 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:23:46 +0000 Subject: [PATCH 059/156] fix: Variable shadowing --- contracts/VotingEscrow.sol | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/contracts/VotingEscrow.sol b/contracts/VotingEscrow.sol index 4e8a9abf..2921b138 100644 --- a/contracts/VotingEscrow.sol +++ b/contracts/VotingEscrow.sol @@ -221,18 +221,18 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _approved Address to be approved for the given NFT ID. /// @param _tokenId ID of the token to be approved. function approve(address _approved, uint _tokenId) public { - address owner = idToOwner[_tokenId]; + address tokenOwner = idToOwner[_tokenId]; // Throws if `_tokenId` is not a valid NFT - require(owner != address(0)); + require(tokenOwner != address(0)); // Throws if `_approved` is the current owner - require(_approved != owner); + require(_approved != tokenOwner); // Check requirements bool senderIsOwner = (idToOwner[_tokenId] == msg.sender); - bool senderIsApprovedForAll = (ownerToOperators[owner])[msg.sender]; + bool senderIsApprovedForAll = (ownerToOperators[tokenOwner])[msg.sender]; require(senderIsOwner || senderIsApprovedForAll); // Set the approval idToApprovals[_tokenId] = _approved; - emit Approval(owner, _approved, _tokenId); + emit Approval(tokenOwner, _approved, _tokenId); } /// @dev Enables or disables approval for a third party ("operator") to manage all of @@ -265,10 +265,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _tokenId uint ID of the token to be transferred /// @return bool whether the msg.sender is approved for the given token ID, is an operator of the owner, or is the owner of the token function _isApprovedOrOwner(address _spender, uint _tokenId) internal view returns (bool) { - address owner = idToOwner[_tokenId]; - bool spenderIsOwner = owner == _spender; + address tokenOwner = idToOwner[_tokenId]; + bool spenderIsOwner = tokenOwner == _spender; bool spenderIsApproved = _spender == idToApprovals[_tokenId]; - bool spenderIsApprovedForAll = (ownerToOperators[owner])[_spender]; + bool spenderIsApprovedForAll = (ownerToOperators[tokenOwner])[_spender]; return spenderIsOwner || spenderIsApproved || spenderIsApprovedForAll; } @@ -501,15 +501,15 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { function _burn(uint _tokenId) internal { require(_isApprovedOrOwner(msg.sender, _tokenId), "caller is not owner nor approved"); - address owner = ownerOf(_tokenId); + address tokenOwner = ownerOf(_tokenId); // Clear approval approve(address(0), _tokenId); // checkpoint for gov - _moveTokenDelegates(delegates(owner), address(0), _tokenId); + _moveTokenDelegates(delegates(tokenOwner), address(0), _tokenId); // Remove token _removeTokenFrom(msg.sender, _tokenId); - emit Transfer(owner, address(0), _tokenId); + emit Transfer(tokenOwner, address(0), _tokenId); } /*////////////////////////////////////////////////////////////// @@ -1261,7 +1261,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } function _moveAllDelegates( - address owner, + address tokenOwner, address srcRep, address dstRep ) internal { @@ -1276,10 +1276,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint[] storage srcRepNew = checkpoints[srcRep][ nextSrcRepNum ].tokenIds; - // All the same except what owner owns + // All the same except what tokenOwner owns for (uint i = 0; i < srcRepOld.length; i++) { uint tId = srcRepOld[i]; - if (idToOwner[tId] != owner) { + if (idToOwner[tId] != tokenOwner) { srcRepNew.push(tId); } } @@ -1296,7 +1296,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint[] storage dstRepNew = checkpoints[dstRep][ nextDstRepNum ].tokenIds; - uint ownerTokenCount = ownerToNFTokenCount[owner]; + uint ownerTokenCount = ownerToNFTokenCount[tokenOwner]; require( dstRepOld.length + ownerTokenCount <= MAX_DELEGATES, "dstRep would have too many tokenIds" @@ -1308,7 +1308,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } // Plus all that's owned for (uint i = 0; i < ownerTokenCount; i++) { - uint tId = ownerToNFTokenIdList[owner][i]; + uint tId = ownerToNFTokenIdList[tokenOwner][i]; dstRepNew.push(tId); } From 52c9cd630bacfdd31ad4f679337f6ed83aaa0663 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:26:50 +0000 Subject: [PATCH 060/156] test: Restrict mutability --- test/utils/TestVoter.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/utils/TestVoter.sol b/test/utils/TestVoter.sol index 14819702..7c8b5a24 100644 --- a/test/utils/TestVoter.sol +++ b/test/utils/TestVoter.sol @@ -20,10 +20,10 @@ contract TestVoter { } function distribute(address _gauge) external { - + } - function isWhitelisted(address token) public returns (bool) { + function isWhitelisted(address token) public pure returns (bool) { return true; } } From 954c5890cd0a3d37e1cc1554b85a618b33c73af7 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:27:37 +0000 Subject: [PATCH 061/156] fix: Unused functiona arg --- test/utils/TestVoter.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/TestVoter.sol b/test/utils/TestVoter.sol index 7c8b5a24..6a33d926 100644 --- a/test/utils/TestVoter.sol +++ b/test/utils/TestVoter.sol @@ -23,7 +23,7 @@ contract TestVoter { } - function isWhitelisted(address token) public pure returns (bool) { + function isWhitelisted(address) public pure returns (bool) { return true; } } From d8d96d07c7641f96992587aacece0149f884a339 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:28:02 +0000 Subject: [PATCH 062/156] fix: Unused local var --- contracts/Router.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Router.sol b/contracts/Router.sol index 03e3beff..a5b5fed2 100644 --- a/contracts/Router.sol +++ b/contracts/Router.sol @@ -478,14 +478,14 @@ contract Router is IRouter { // requires the initial amount to have already been sent to the first pair function _swapSupportingFeeOnTransferTokens(route[] memory routes, address _to) internal virtual { for (uint i; i < routes.length; i++) { - (address input, address output, bool stable) = (routes[i].from, routes[i].to, routes[i].stable); + (address input, address output,) = (routes[i].from, routes[i].to, routes[i].stable); (address token0,) = sortTokens(input, output); IPair pair = IPair(pairFor(routes[i].from, routes[i].to, routes[i].stable)); uint amountInput; uint amountOutput; { // scope to avoid stack too deep errors (uint reserve0, uint reserve1,) = pair.getReserves(); - (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); + (uint reserveInput,) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput; amountOutput = pair.getAmountOut(amountInput, input); } From 8eaeb5a8e08e9e7a8c5818807d6aa89e8104ec46 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:38:14 +0000 Subject: [PATCH 063/156] fix: set hasGauge/external bribe does not work if _pool is not pair --- contracts/Voter.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 7716e2a3..1f1f6af4 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -79,7 +79,7 @@ contract Voter is IVoter { } modifier onlyNewEpoch(uint _tokenId) { - // ensure new epoch since last vote + // ensure new epoch since last vote require((block.timestamp / DURATION) * DURATION > lastVoted[_tokenId], "TOKEN_ALREADY_VOTED_THIS_EPOCH"); _; } @@ -241,8 +241,10 @@ contract Voter is IVoter { isAlive[_gauge] = true; _updateFor(_gauge); pools.push(_pool); - IPair(_pool).setHasGauge(true); - IPair(_pool).setExternalBribe(_wxbribe); + if (isPair) { + IPair(_pool).setHasGauge(true); + IPair(_pool).setExternalBribe(_wxbribe); + } emit GaugeCreated(_gauge, msg.sender, _external_bribe, _wxbribe, _pool); return _gauge; } From 327ee1b978055255ca138b7ad5e8ea9e30b45335 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:40:57 +0000 Subject: [PATCH 064/156] fix: Voter cannot change in Pair, so no need to emit setter --- contracts/Pair.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 7f9e1ba4..4f8fe734 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -78,8 +78,8 @@ contract Pair is IPair { event Transfer(address indexed from, address indexed to, uint amount); event Approval(address indexed owner, address indexed spender, uint amount); - event ExternalBribeSet(address indexed setter, address indexed externalBribe); - event HasGaugeSet(address indexed setter, bool value); + event ExternalBribeSet(address indexed externalBribe); + event HasGaugeSet(bool value); constructor() { factory = msg.sender; @@ -122,13 +122,13 @@ contract Pair is IPair { externalBribe = _externalBribe; _safeApprove(token0, externalBribe, type(uint).max); _safeApprove(token1, externalBribe, type(uint).max); - emit ExternalBribeSet(msg.sender, _externalBribe); + emit ExternalBribeSet(_externalBribe); } function setHasGauge(bool value) external { require(msg.sender == voter, 'Only voter can set has gauge'); hasGauge = value; - emit HasGaugeSet(msg.sender, value); + emit HasGaugeSet(value); } function observationLength() external view returns (uint) { From acdc6db929e7e39264a1c24c82da8899f9580229 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:44:49 +0000 Subject: [PATCH 065/156] fix: Failing testMinterWeeklyDistribute --- test/Minter.t.sol | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 0095f12c..fdc9a7d2 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -85,51 +85,64 @@ contract MinterTest is BaseTest { minter.update_period(); assertEq(minter.weekly(), 15 * TOKEN_1M); // 15M - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + + _elapseOneWeek(); + minter.update_period(); assertEq(distributor.claimable(1), 0); assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + + _elapseOneWeek(); + minter.update_period(); uint256 claimable = distributor.claimable(1); assertGt(claimable, 128115516517529); + distributor.claim(1); assertEq(distributor.claimable(1), 0); uint256 weekly = minter.weekly(); + console2.log(weekly); console2.log(minter.calculate_growth(weekly)); console2.log(FLOW.totalSupply()); console2.log(escrow.totalSupply()); - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + _elapseOneWeek(); + minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim(1); - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + + _elapseOneWeek(); + minter.update_period(); console2.log(distributor.claimable(1)); uint256[] memory tokenIds = new uint256[](1); tokenIds[0] = 1; distributor.claim_many(tokenIds); - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + + _elapseOneWeek(); + minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim(1); - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + + _elapseOneWeek(); + minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim_many(tokenIds); - vm.warp(block.timestamp + ONE_WEEK); - vm.roll(block.number + 1); + + _elapseOneWeek(); + minter.update_period(); console2.log(distributor.claimable(1)); distributor.claim(1); } + + function _elapseOneWeek() private { + vm.warp(block.timestamp + ONE_WEEK); + vm.roll(block.number + 1); + } } From b003e5be87cd1a1d4eb1972e764543c7baa39c96 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 14:57:26 +0000 Subject: [PATCH 066/156] build: forge install ds-test --- lib/ds-test | 1 + 1 file changed, 1 insertion(+) create mode 160000 lib/ds-test diff --git a/lib/ds-test b/lib/ds-test new file mode 160000 index 00000000..e282159d --- /dev/null +++ b/lib/ds-test @@ -0,0 +1 @@ +Subproject commit e282159d5170298eb2455a6c05280ab5a73a4ef0 From 54d37e0d39eb97be5c52bda44e98c8ece6cf17e0 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 15:22:13 +0000 Subject: [PATCH 067/156] fix: Failing testMinterWeeklyDistribute --- test/Minter.t.sol | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/Minter.t.sol b/test/Minter.t.sol index fdc9a7d2..230b2bb4 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -96,7 +96,15 @@ contract MinterTest is BaseTest { minter.update_period(); uint256 claimable = distributor.claimable(1); - assertGt(claimable, 128115516517529); + /** + * This has been updated from 128115516517529 to + * 197073360700 because originally in VELO the + * constructor mints 0 tokens, but now we are minting + * an initial supply instead of using the initialMint + * function. + */ + + assertGt(claimable, 197073360700); distributor.claim(1); assertEq(distributor.claimable(1), 0); From 6a5eedc84b5d51eb12c11c8f7df4497d93d03814 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 15:47:15 +0000 Subject: [PATCH 068/156] test: Remove WEVE --- test/BaseTest.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 45b0ca93..57b3c2fb 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -47,7 +47,6 @@ abstract contract BaseTest is Test, TestOwner { MockERC20 DAI; TestWETH WETH; // Mock WETH token Flow FLOW; - MockERC20 WEVE; MockERC20 LR; // late reward TestToken stake; PairFactory factory; @@ -72,7 +71,6 @@ abstract contract BaseTest is Test, TestOwner { FRAX = new MockERC20("FRAX", "FRAX", 18); DAI = new MockERC20("DAI", "DAI", 18); FLOW = new Flow(msg.sender); - WEVE = new MockERC20("WEVE", "WEVE", 18); LR = new MockERC20("LR", "LR", 18); WETH = new TestWETH(); stake = new TestToken("stake", "stake", 18, address(owner)); From a4cc42d4c73d306d826aace85a406fa304fd1663 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 16:09:01 +0000 Subject: [PATCH 069/156] build: Canto deployment script --- scripts/Deployment.s.sol | 205 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 scripts/Deployment.s.sol diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol new file mode 100644 index 00000000..49001dc6 --- /dev/null +++ b/scripts/Deployment.s.sol @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +// Scripting tool +import {Script} from "../lib/forge-std/src/Script.sol"; + +import {Flow} from "../contracts/Flow.sol"; +import {GaugeFactory} from "../contracts/factories/GaugeFactory.sol"; +import {BribeFactory} from "../contracts/factories/BribeFactory.sol"; +import {PairFactory} from "../contracts/factories/PairFactory.sol"; +import {WrappedExternalBribeFactory} from "../contracts/factories/WrappedExternalBribeFactory.sol"; +import {Router} from "../contracts/Router.sol"; +import {VelocimeterLibrary} from "../contracts/VelocimeterLibrary.sol"; +import {VeArtProxy} from "../contracts/VeArtProxy.sol"; +import {VotingEscrow} from "../contracts/VotingEscrow.sol"; +import {RewardsDistributor} from "../contracts/RewardsDistributor.sol"; +import {Voter} from "../contracts/Voter.sol"; +import {Minter} from "../contracts/Minter.sol"; + +contract Deployment is Script { + // token addresses + address private constant WCANTO = 0x826551890dc65655a0aceca109ab11abdbd7a07b; + + // privileged accounts + address private constant COUNCIL = 0x06b16991b53632c2362267579ae7c4863c72fdb8; + address private constant TEAM_MULTI_SIG = 0x13eeB8EdfF60BbCcB24Ec7Dd5668aa246525Dc51; + address private constant GOVERNOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; + address private constant TANK = 0x0A868fd1523a1ef58Db1F2D135219F0e30CBf7FB; + + // address to receive veNFT to be distributed to partners in the future + address private constant FLOW_VOTER_EOA = 0xcC06464C7bbCF81417c08563dA2E1847c22b703a; + + // team member addresses + address private constant DUNKS = 0x069e85d4f1010dd961897dc8c095fbb5ff297434; + address private constant T0RB1K = 0x0b776552c1aef1dc33005dd25acda22493b6615d; + address private constant CEAZOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; + address private constant MOTTO = 0x78e801136f77805239a7f533521a7a5570f572c8; + address private constant COOLIE = 0x03b88dacb7c21b54cefecc297d981e5b721a9df1; + + // token amounts + uint256 private constant ONE_MILLION = 1e24; // 1e24 == 1e6 (1m) ** 1e18 (decimals) + uint256 private constant TWO_MILLION = 2e24; // 2e24 == 1e6 (1m) ** 1e18 (decimals) + uint256 private constant FOUR_MILLION = 4e24; // 4e24 == 1e6 (1m) ** 1e18 (decimals) + + // time + uint256 private constant ONE_YEAR = 31_536_000; + uint256 private constant TWO_YEARS = 63_072_000; + uint256 private constant FOUR_YEARS = 126_144_000; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + vm.startBroadcast(deployerPrivateKey); + + // Flow token + Flow flow = new Flow({initialSupplyRecipient: address(this)}); + + // Gauge factory + GaugeFactory gaugeFactory = new GaugeFactory(); + + // Bribe factory + BribeFactory bribeFactory = new BribeFactory(); + + // Pair factory + PairFactory pairFactory = new PairFactory(); + + // Router + Router router = new Router(address(pairFactory), WCANTO); + + // VelocimeterLibrary + VelocimeterLibrary velocimeterLib = new VelocimeterLibrary(address(router)); + + // VeArtProxy + VeArtProxy veArtProxy = new VeArtProxy(); + + // VotingEscrow + VotingEscrow votingEscrow = new VotingEscrow(address(flow), address(veArtProxy), TEAM_MULTI_SIG); + + // RewardsDistributor + RewardsDistributor rewardsDistributor = new RewardsDistributor(address(votingEscrow)); + + // Wrapped external bribe factory + WrappedExternalBribeFactory wrappedExternalBribeFactory = new WrappedExternalBribeFactory(); + + // Voter + Voter voter = new Voter( + address(votingEscrow), + address(pairFactory), + address(gaugeFactory), + address(bribeFactory), + address(wrappedExternalBribeFactory) + ); + + // Set voter + wrappedExternalBribeFactory.setVoter(address(voter)); + votingEscrow.setVoter(address(voter)); + pairFactory.setVoter(address(voter)); + + // Minter + Minter minter = new Minter( + address(voter), + address(votingEscrow), + address(rewardsDistributor) + ); + // TODO: Minter.initialize, Minter.setTeam + + // Set flow minter to contract + flow.setMinter(address(minter)); + + // Set pair factory pauser + pairFactory.setPauser(TEAM_MULTI_SIG); + + // Set voting escrow's voter + votingEscrow.setVoter(address(voter)); + + // Set minter and voting escrow's team + votingEscrow.setTeam(TEAM_MULTI_SIG); + minter.setTeam(TEAM_MULTI_SIG); + + // Set voter's governor + voter.setGovernor(TEAM_MULTI_SIG); + + // Set voter's emergency council + voter.setEmergencyCouncil(TEAM_MULTI_SIG); + + // Set rewards distributor's depositor to minter contract + rewardsDistributor.setDepositor(address(minter)); + + // Initialize tokens for voter + // TODO: Get all the whitelisted tokens + address[] memory whitelistedTokens = new address[](2); + whitelistedTokens[0] = address(flow); + voter.initialize(whitelistedTokens, address(minter)); + + // Mint tokens and lock for veNFT + address[] memory claimants = new claimants[](); + uint256[] memory amounts = new amounts[](); + + // 1. Mint to Flow voter EOA + claimants[0] = FLOW_VOTER_EOA; + claimants[1] = FLOW_VOTER_EOA; + claimants[2] = FLOW_VOTER_EOA; + claimants[3] = FLOW_VOTER_EOA; + claimants[4] = FLOW_VOTER_EOA; + claimants[5] = FLOW_VOTER_EOA; + claimants[6] = FLOW_VOTER_EOA; + claimants[7] = FLOW_VOTER_EOA; + claimants[8] = FLOW_VOTER_EOA; + claimants[9] = FLOW_VOTER_EOA; + claimants[10] = FLOW_VOTER_EOA; + claimants[11] = FLOW_VOTER_EOA; + claimants[12] = FLOW_VOTER_EOA; + + amounts[0] = ONE_MILLION; + amounts[1] = ONE_MILLION; + amounts[2] = ONE_MILLION; + amounts[3] = ONE_MILLION; + amounts[4] = ONE_MILLION; + amounts[5] = TWO_MILLION; + amounts[6] = TWO_MILLION; + amounts[7] = TWO_MILLION; + amounts[8] = TWO_MILLION; + amounts[9] = TWO_MILLION; + amounts[10] = FOUR_MILLION; + amounts[11] = FOUR_MILLION; + amounts[12] = FOUR_MILLION; + + // 2. Mint to team members + claimants[13] = DUNKS; + claimants[14] = T0RB1K; + claimants[15] = T0RB1K; + claimants[16] = T0RB1K; + claimants[17] = CEAZOR; + claimants[18] = CEAZOR; + claimants[19] = CEAZOR; + claimants[20] = MOTTO; + claimants[21] = MOTTO; + claimants[22] = MOTTO; + claimants[22] = COOLIE; + claimants[23] = COOLIE; + claimants[24] = COOLIE; + + amounts[13] = FOUR_MILLION; + amounts[14] = FOUR_MILLION; + amounts[15] = FOUR_MILLION; + amounts[16] = FOUR_MILLION; + amounts[17] = FOUR_MILLION; + amounts[18] = FOUR_MILLION; + amounts[19] = FOUR_MILLION; + amounts[20] = FOUR_MILLION; + amounts[21] = FOUR_MILLION; + amounts[22] = FOUR_MILLION; + amounts[22] = FOUR_MILLION; + amounts[23] = FOUR_MILLION; + amounts[24] = FOUR_MILLION; + + minter.initialize( + claimants, + amounts, + max + ); + + vm.stopBroadcast(); + } +} From a44dafc9ae9df9cea3fdee4ed114023f719a54bc Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 17:08:06 +0000 Subject: [PATCH 070/156] refactor: Minter.initialize Claim struct --- contracts/Minter.sol | 17 +++++++++++++---- test/ExternalBribes.t.sol | 5 ++--- test/Minter.t.sol | 13 ++++++++----- test/MinterTeamEmissions.t.sol | 13 ++++++++----- test/Pair.t.sol | 14 +++++++++----- test/VeloVoting.t.sol | 13 ++++++++----- test/WrappedExternalBribes.t.sol | 5 ++--- 7 files changed, 50 insertions(+), 30 deletions(-) diff --git a/contracts/Minter.sol b/contracts/Minter.sol index 6ee5e8e2..f483f268 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -32,6 +32,12 @@ contract Minter is IMinter { event Mint(address indexed sender, uint weekly, uint circulating_supply, uint circulating_emission); + struct Claim { + address claimant; + uint256 amount; + uint256 lockTime; + } + constructor( address __voter, // the voting & distribution system address __ve, // the ve(3,3) system that will be locked into @@ -48,15 +54,18 @@ contract Minter is IMinter { } function initialize( - address[] memory claimants, // partnerAddrs - uint[] memory amounts, // partnerAmounts + Claim[] calldata claims, uint max // sum amounts / max = % ownership of top protocols, so if initial 20m is distributed, and target is 25% protocol ownership, then max - 4 x 20m = 80m ) external { require(initializer == msg.sender); _flow.mint(address(this), max); _flow.approve(address(_ve), type(uint).max); - for (uint i = 0; i < claimants.length; i++) { - _ve.create_lock_for(amounts[i], LOCK, claimants[i]); + uint256 length = claims.length; + for (uint i = 0; i < length;) { + _ve.create_lock_for(claims[i].amount, claims[i].lockTime, claims[i].claimant); + unchecked { + ++i; + } } initializer = address(0); active_period = ((block.timestamp) / WEEK) * WEEK; // allow minter.update_period() to mint new emissions THIS Thursday diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index 6b54479a..f2fc8500 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -54,9 +54,8 @@ contract ExternalBribesTest is BaseTest { tokens[4] = address(LR); voter.initialize(tokens, address(minter)); - address[] memory claimants = new address[](0); - uint[] memory amounts1 = new uint[](0); - minter.initialize(claimants, amounts1, 0); + Minter.Claim[] memory claims = new Minter.Claim[](0); + minter.initialize(claims, 0); // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 230b2bb4..b22220f7 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -69,11 +69,14 @@ contract MinterTest is BaseTest { function initializeVotingEscrow() public { deployBase(); - address[] memory claimants = new address[](1); - claimants[0] = address(owner); - uint256[] memory amounts = new uint256[](1); - amounts[0] = TOKEN_1M; - minter.initialize(claimants, amounts, 2e25); + Minter.Claim[] memory claims = new Minter.Claim[](1); + claims[0] = Minter.Claim({ + claimant: address(owner), + amount: TOKEN_1M, + lockTime: 86400 * 7 * 52 * 4 + }); + minter.initialize(claims, 2e25); + assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index bff7a27f..f863e0aa 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -85,11 +85,14 @@ contract MinterTeamEmissions is BaseTest { weights[0] = 5000; voter.vote(1, pools, weights); - address[] memory claimants = new address[](1); - claimants[0] = address(owner); - uint256[] memory amountsToMint = new uint256[](1); - amountsToMint[0] = TOKEN_1M; - minter.initialize(claimants, amountsToMint, 15 * TOKEN_1M); + Minter.Claim[] memory claims = new Minter.Claim[](1); + claims[0] = Minter.Claim({ + claimant: address(owner), + amount: TOKEN_1M, + lockTime: 86400 * 7 * 52 * 4 + }); + minter.initialize(claims, 15 * TOKEN_1M); + assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 194bb332..c1e9242a 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -591,11 +591,15 @@ contract PairTest is BaseTest { console2.log(distributor.last_token_time()); console2.log(distributor.timestamp()); - address[] memory claimants = new address[](1); - claimants[0] = address(owner); - uint256[] memory amounts = new uint256[](1); - amounts[0] = TOKEN_1; - minter.initialize(claimants, amounts, TOKEN_1); + + Minter.Claim[] memory claims = new Minter.Claim[](1); + claims[0] = Minter.Claim({ + claimant: address(owner), + amount: TOKEN_1, + lockTime: 86400 * 7 * 52 * 4 + }); + minter.initialize(claims, TOKEN_1); + minter.update_period(); voter.updateGauge(address(gauge)); console2.log(FLOW.balanceOf(address(distributor))); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 43fefd34..4feeb30d 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -87,11 +87,14 @@ contract VeloVotingTest is BaseTest { weights[0] = 5000; voter.vote(1, pools, weights); - address[] memory claimants = new address[](1); - claimants[0] = address(owner); - uint256[] memory amountsToMint = new uint256[](1); - amountsToMint[0] = TOKEN_1M; - minter.initialize(claimants, amountsToMint, 15 * TOKEN_1M); + Minter.Claim[] memory claims = new Minter.Claim[](1); + claims[0] = Minter.Claim({ + claimant: address(owner), + amount: TOKEN_1M, + lockTime: 86400 * 7 * 52 * 4 + }); + minter.initialize(claims, 15 * TOKEN_1M); + assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index d99d7093..3991c92c 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -56,9 +56,8 @@ contract WrappedExternalBribesTest is BaseTest { tokens[4] = address(LR); voter.initialize(tokens, address(minter)); - address[] memory claimants = new address[](0); - uint[] memory amounts1 = new uint[](0); - minter.initialize(claimants, amounts1, 0); + Minter.Claim[] memory claims = new Minter.Claim[](0); + minter.initialize(claims, 0); // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); From ff436dc5d1bc3b0746d8cc508c5fc224a344a79d Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 17:12:11 +0000 Subject: [PATCH 071/156] build: Mint initialize in deployment --- scripts/Deployment.s.sol | 117 ++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 49001dc6..fde99433 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -29,6 +29,7 @@ contract Deployment is Script { // address to receive veNFT to be distributed to partners in the future address private constant FLOW_VOTER_EOA = 0xcC06464C7bbCF81417c08563dA2E1847c22b703a; + address private constant ASSET_EOA = 0x1bae1083cf4125ed5deeb778985c1effac0ecc06; // team member addresses address private constant DUNKS = 0x069e85d4f1010dd961897dc8c095fbb5ff297434; @@ -133,66 +134,70 @@ contract Deployment is Script { voter.initialize(whitelistedTokens, address(minter)); // Mint tokens and lock for veNFT - address[] memory claimants = new claimants[](); - uint256[] memory amounts = new amounts[](); + Minter.Claim[] memory claims = new Minter.Claim[](30); // 1. Mint to Flow voter EOA - claimants[0] = FLOW_VOTER_EOA; - claimants[1] = FLOW_VOTER_EOA; - claimants[2] = FLOW_VOTER_EOA; - claimants[3] = FLOW_VOTER_EOA; - claimants[4] = FLOW_VOTER_EOA; - claimants[5] = FLOW_VOTER_EOA; - claimants[6] = FLOW_VOTER_EOA; - claimants[7] = FLOW_VOTER_EOA; - claimants[8] = FLOW_VOTER_EOA; - claimants[9] = FLOW_VOTER_EOA; - claimants[10] = FLOW_VOTER_EOA; - claimants[11] = FLOW_VOTER_EOA; - claimants[12] = FLOW_VOTER_EOA; - - amounts[0] = ONE_MILLION; - amounts[1] = ONE_MILLION; - amounts[2] = ONE_MILLION; - amounts[3] = ONE_MILLION; - amounts[4] = ONE_MILLION; - amounts[5] = TWO_MILLION; - amounts[6] = TWO_MILLION; - amounts[7] = TWO_MILLION; - amounts[8] = TWO_MILLION; - amounts[9] = TWO_MILLION; - amounts[10] = FOUR_MILLION; - amounts[11] = FOUR_MILLION; - amounts[12] = FOUR_MILLION; + for (uint256 i = 0; i <= 4; i++) { + claims[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: ONE_MILLION, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 5; i <= 9; i++) { + claims[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: TWO_MILLION, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 10; i <= 12; i++) { + claims[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } // 2. Mint to team members - claimants[13] = DUNKS; - claimants[14] = T0RB1K; - claimants[15] = T0RB1K; - claimants[16] = T0RB1K; - claimants[17] = CEAZOR; - claimants[18] = CEAZOR; - claimants[19] = CEAZOR; - claimants[20] = MOTTO; - claimants[21] = MOTTO; - claimants[22] = MOTTO; - claimants[22] = COOLIE; - claimants[23] = COOLIE; - claimants[24] = COOLIE; - - amounts[13] = FOUR_MILLION; - amounts[14] = FOUR_MILLION; - amounts[15] = FOUR_MILLION; - amounts[16] = FOUR_MILLION; - amounts[17] = FOUR_MILLION; - amounts[18] = FOUR_MILLION; - amounts[19] = FOUR_MILLION; - amounts[20] = FOUR_MILLION; - amounts[21] = FOUR_MILLION; - amounts[22] = FOUR_MILLION; - amounts[22] = FOUR_MILLION; - amounts[23] = FOUR_MILLION; - amounts[24] = FOUR_MILLION; + claims[13] = Minter.Claim({claimant: DUNKS, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + + for (uint256 i = 14; i <= 16; i++) { + claims[i] = Minter.Claim({claimant: T0RB1K, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 17; i <= 19; i++) { + claims[i] = Minter.Claim({claimant: CEAZOR, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 20; i <= 22; i++) { + claims[i] = Minter.Claim({claimant: MOTTO, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 23; i <= 25; i++) { + claims[i] = Minter.Claim({claimant: COOLIE, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + + // 3. Mint to snapshotted veNFT holders + + // 4. Mint for future partners + for (uint256 i = 26; i <= 28; i++) { + claims[i] = Minter.Claim({amount: FOUR_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 29; i <= 42; i++) { + claims[i] = Minter.Claim({amount: FOUR_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 43; i <= 45; i++) { + claims[i] = Minter.Claim({amount: TWO_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 46; i <= 60; i++) { + claims[i] = Minter.Claim({amount: TWO_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 61; i <= 76; i++) { + claims[i] = Minter.Claim({amount: ONE_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + } + + for (uint256 i = 77; i <= 81; i++) { + claims[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: TWO_YEARS}); + } + + for (uint256 i = 82; i <= 86; i++) { + claims[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: ONE_YEAR}); + } minter.initialize( claimants, From dfba09e19d59c1460c2b20393b41ff5cda19ec69 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 18:37:10 +0000 Subject: [PATCH 072/156] build: Script to get veNFT snapshot --- scripts/VeNFTSnapshot.s.sol | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 scripts/VeNFTSnapshot.s.sol diff --git a/scripts/VeNFTSnapshot.s.sol b/scripts/VeNFTSnapshot.s.sol new file mode 100644 index 00000000..f993121c --- /dev/null +++ b/scripts/VeNFTSnapshot.s.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +// Scripting tool +import "forge-std/console2.sol"; +import {Script} from "../lib/forge-std/src/Script.sol"; + +import {VotingEscrow} from "../contracts/VotingEscrow.sol"; + +contract VeNFTSnapshot is Script { + function run() external view { + VotingEscrow votingEscrow = VotingEscrow(0x990efF367C6c4aece43c1E98099061c897730F27); + // From https://alto.build/collections/0x990eff367c6c4aece43c1e98099061c897730f27 + uint256 currentTokenId = 0; + uint256 maxTokenId = 267; + while (currentTokenId <= maxTokenId) { + address owner = votingEscrow.ownerOf(currentTokenId); + + if (owner != address(0)) { + (int128 lockAmount,) = votingEscrow.locked(currentTokenId); + + console2.log("Token ID: "); + console2.log(currentTokenId); + console2.log("Owner: "); + console2.log(owner); + console2.log("Locked amount: "); + console2.log(lockAmount); + } + + currentTokenId++; + } + } +} From f007ddb3cc22f97a1a3d7b21fead81a98cd5e286 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:18:12 +0000 Subject: [PATCH 073/156] feat: Allow minter multiple mint and lock --- contracts/Minter.sol | 11 ++++++++--- scripts/Deployment.s.sol | 1 + tasks/deploy/op.ts | 4 +++- test/ExternalBribes.t.sol | 3 ++- test/Minter.t.sol | 3 ++- test/MinterTeamEmissions.t.sol | 3 ++- test/Pair.t.sol | 3 ++- test/VeloVoting.t.sol | 3 ++- test/WrappedExternalBribes.t.sol | 3 ++- 9 files changed, 24 insertions(+), 10 deletions(-) diff --git a/contracts/Minter.sol b/contracts/Minter.sol index f483f268..4e648c05 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -53,11 +53,11 @@ contract Minter is IMinter { active_period = ((block.timestamp + (2 * WEEK)) / WEEK) * WEEK; } - function initialize( + function initialMintAndLock( Claim[] calldata claims, uint max // sum amounts / max = % ownership of top protocols, so if initial 20m is distributed, and target is 25% protocol ownership, then max - 4 x 20m = 80m ) external { - require(initializer == msg.sender); + require(initializer == msg.sender, "not initializer"); _flow.mint(address(this), max); _flow.approve(address(_ve), type(uint).max); uint256 length = claims.length; @@ -67,8 +67,13 @@ contract Minter is IMinter { ++i; } } + } + + function startActivePeriod() external { + require(initializer == msg.sender, "not initializer"); initializer = address(0); - active_period = ((block.timestamp) / WEEK) * WEEK; // allow minter.update_period() to mint new emissions THIS Thursday + // allow minter.update_period() to mint new emissions THIS Thursday + active_period = ((block.timestamp) / WEEK) * WEEK; } function setTeam(address _team) external { diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index fde99433..754f16c8 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -204,6 +204,7 @@ contract Deployment is Script { amounts, max ); + minter.startActivePeriod(); vm.stopBroadcast(); } diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index 4843d3fe..488c0867 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -148,13 +148,15 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( console.log("Whitelist set"); // Initial veFLOW distro - await minter.initialize( + await minter.initialMintAndLock( OP_CONFIG.partnerAddrs, OP_CONFIG.partnerAmts, OP_CONFIG.partnerMax ); + await minter.startActivePeriod(); console.log("veFLOW distributed"); + await minter.setTeam(OP_CONFIG.teamMultisig) console.log("Team set for minter"); diff --git a/test/ExternalBribes.t.sol b/test/ExternalBribes.t.sol index f2fc8500..be390724 100644 --- a/test/ExternalBribes.t.sol +++ b/test/ExternalBribes.t.sol @@ -55,7 +55,8 @@ contract ExternalBribesTest is BaseTest { voter.initialize(tokens, address(minter)); Minter.Claim[] memory claims = new Minter.Claim[](0); - minter.initialize(claims, 0); + minter.initialMintAndLock(claims, 0); + minter.startActivePeriod(); // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); diff --git a/test/Minter.t.sol b/test/Minter.t.sol index b22220f7..39a8f1c0 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -75,7 +75,8 @@ contract MinterTest is BaseTest { amount: TOKEN_1M, lockTime: 86400 * 7 * 52 * 4 }); - minter.initialize(claims, 2e25); + minter.initialMintAndLock(claims, 2e25); + minter.startActivePeriod(); assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index f863e0aa..9a0f9a5f 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -91,7 +91,8 @@ contract MinterTeamEmissions is BaseTest { amount: TOKEN_1M, lockTime: 86400 * 7 * 52 * 4 }); - minter.initialize(claims, 15 * TOKEN_1M); + minter.initialMintAndLock(claims, 15 * TOKEN_1M); + minter.startActivePeriod(); assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); diff --git a/test/Pair.t.sol b/test/Pair.t.sol index c1e9242a..fc2088d8 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -598,7 +598,8 @@ contract PairTest is BaseTest { amount: TOKEN_1, lockTime: 86400 * 7 * 52 * 4 }); - minter.initialize(claims, TOKEN_1); + minter.initialMintAndLock(claims, TOKEN_1); + minter.startActivePeriod(); minter.update_period(); voter.updateGauge(address(gauge)); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 4feeb30d..3bcd3dcb 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -93,7 +93,8 @@ contract VeloVotingTest is BaseTest { amount: TOKEN_1M, lockTime: 86400 * 7 * 52 * 4 }); - minter.initialize(claims, 15 * TOKEN_1M); + minter.initialMintAndLock(claims, 15 * TOKEN_1M); + minter.startActivePeriod(); assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index 3991c92c..a2284db4 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -57,7 +57,8 @@ contract WrappedExternalBribesTest is BaseTest { voter.initialize(tokens, address(minter)); Minter.Claim[] memory claims = new Minter.Claim[](0); - minter.initialize(claims, 0); + minter.initialMintAndLock(claims, 0); + minter.startActivePeriod(); // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); From 1fd989bc91f9bb34e0ec0eb7e258c4f40b8b1578 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:31:46 +0000 Subject: [PATCH 074/156] build: Split batch mint tokens + veNFTs --- contracts/Minter.sol | 2 +- scripts/Deployment.s.sol | 94 +++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/contracts/Minter.sol b/contracts/Minter.sol index 4e648c05..e5f9e041 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -59,7 +59,7 @@ contract Minter is IMinter { ) external { require(initializer == msg.sender, "not initializer"); _flow.mint(address(this), max); - _flow.approve(address(_ve), type(uint).max); + _flow.approve(address(_ve), max); uint256 length = claims.length; for (uint i = 0; i < length;) { _ve.create_lock_for(claims[i].amount, claims[i].lockTime, claims[i].claimant); diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 754f16c8..805ef56a 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -134,76 +134,100 @@ contract Deployment is Script { voter.initialize(whitelistedTokens, address(minter)); // Mint tokens and lock for veNFT - Minter.Claim[] memory claims = new Minter.Claim[](30); // 1. Mint to Flow voter EOA - for (uint256 i = 0; i <= 4; i++) { - claims[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: ONE_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory flowVoterEOAClaim1 = new Minter.Claim[](4); + for (uint256 i; i < flowVoterEOAClaim1.length; i++) { + flowVoterEOAClaim1[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: ONE_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(flowVoterEOAClaim1, ONE_MILLION * 5); - for (uint256 i = 5; i <= 9; i++) { - claims[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: TWO_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory flowVoterEOAClaim2 = new Minter.Claim[](5); + for (uint256 i; i < flowVoterEOAClaim2.length; i++) { + flowVoterEOAClaim2[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: TWO_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(flowVoterEOAClaim2, TWO_MILLION * 5); - for (uint256 i = 10; i <= 12; i++) { - claims[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory flowVoterEOAClaim3 = new Minter.Claim[](3); + for (uint256 i; i < flowVoterEOAClaim3.length; i++) { + flowVoterEOAClaim3[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(flowVoterEOAClaim3, FOUR_MILLION * 3); // 2. Mint to team members - claims[13] = Minter.Claim({claimant: DUNKS, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory dunksClaim = new Minter.Claim[](1); + dunksClaim[0] = Minter.Claim({claimant: DUNKS, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + minter.initialMintAndLock(dunksClaim, FOUR_MILLION); - for (uint256 i = 14; i <= 16; i++) { - claims[i] = Minter.Claim({claimant: T0RB1K, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory t0rb1kClaim = new Minter.Claim[](3); + for (uint256 i; i < t0rb1kClaim.length; i++) { + t0rb1kClaim[i] = Minter.Claim({claimant: T0RB1K, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(t0rb1kClaim, FOUR_MILLION * 3); - for (uint256 i = 17; i <= 19; i++) { - claims[i] = Minter.Claim({claimant: CEAZOR, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory ceazorClaim = new Minter.Claim[](3); + for (uint256 i; i < ceazorClaim.length; i++) { + ceazorClaim[i] = Minter.Claim({claimant: CEAZOR, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(ceazorClaim, FOUR_MILLION * 3); - for (uint256 i = 20; i <= 22; i++) { - claims[i] = Minter.Claim({claimant: MOTTO, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory mottoClaim = new Minter.Claim[](3); + for (uint256 i; i < mottoClaim.length; i++) { + mottoClaim[i] = Minter.Claim({claimant: MOTTO, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(mottoClaim, FOUR_MILLION * 3); - for (uint256 i = 23; i <= 25; i++) { - claims[i] = Minter.Claim({claimant: COOLIE, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + Minter.Claim[] memory coolieClaim = new Minter.Claim[](3); + for (uint256 i; i < coolieClaim.length; i++) { + coolieClaim[i] = Minter.Claim({claimant: COOLIE, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(coolieClaim, FOUR_MILLION * 3); // 3. Mint to snapshotted veNFT holders // 4. Mint for future partners - for (uint256 i = 26; i <= 28; i++) { - claims[i] = Minter.Claim({amount: FOUR_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); + Minter.Claim[] memory assetEOAClaim1 = new Minter.Claim[](3); + for (uint256 i; i < assetEOAClaim1.length; i++) { + assetEOAClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(assetEOAClaim1, FOUR_MILLION * 3); - for (uint256 i = 29; i <= 42; i++) { - claims[i] = Minter.Claim({amount: FOUR_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + Minter.Claim[] memory multiSigClaim1 = new Minter.Claim[](14); + for (uint256 i; i < multiSigClaim1.length; i++) { + multiSigClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(multiSigClaim1, FOUR_MILLION * 14); - for (uint256 i = 43; i <= 45; i++) { - claims[i] = Minter.Claim({amount: TWO_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); + Minter.Claim[] memory assetEOAClaim2 = new Minter.Claim[](3); + for (uint256 i; i < assetEOAClaim2.length; i++) { + assetEOAClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(assetEOAClaim1, TWO_MILLION * 3); - for (uint256 i = 46; i <= 60; i++) { - claims[i] = Minter.Claim({amount: TWO_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + Minter.Claim[] memory multiSigClaim2 = new Minter.Claim[](15); + for (uint256 i; i < multiSigClaim2.length; i++) { + multiSigClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(multiSigClaim2, TWO_MILLION * 15); - for (uint256 i = 61; i <= 76; i++) { - claims[i] = Minter.Claim({amount: ONE_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + Minter.Claim[] memory multiSigClaim3 = new Minter.Claim[](16); + for (uint256 i; i < multiSigClaim3.length; i++) { + multiSigClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); } + minter.initialMintAndLock(multiSigClaim3, ONE_MILLION * 16); - for (uint256 i = 77; i <= 81; i++) { - claims[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: TWO_YEARS}); + Minter.Claim[] memory assetEOAClaim3 = new Minter.Claim[](5); + for (uint256 i; i < assetEOAClaim3.length; i++) { + assetEOAClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: TWO_YEARS}); } + minter.initialMintAndLock(assetEOAClaim3, ONE_MILLION * 5); - for (uint256 i = 82; i <= 86; i++) { - claims[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: ONE_YEAR}); + Minter.Claim[] memory assetEOAClaim4 = new Minter.Claim[](5); + for (uint256 i; i < assetEOAClaim4.length; i++) { + assetEOAClaim4[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: ONE_YEAR}); } + minter.initialMintAndLock(assetEOAClaim4, ONE_MILLION * 5); - minter.initialize( - claimants, - amounts, - max - ); minter.startActivePeriod(); vm.stopBroadcast(); From d886441a3cbd8756c5d26e6472966e71766e1572 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:38:45 +0000 Subject: [PATCH 075/156] build: Migrate mint script --- scripts/Deployment.s.sol | 118 -------------------------- scripts/InitialMintAndLock.s.sol | 141 +++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 118 deletions(-) create mode 100644 scripts/InitialMintAndLock.s.sol diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 805ef56a..e2b9da2f 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -27,27 +27,6 @@ contract Deployment is Script { address private constant GOVERNOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; address private constant TANK = 0x0A868fd1523a1ef58Db1F2D135219F0e30CBf7FB; - // address to receive veNFT to be distributed to partners in the future - address private constant FLOW_VOTER_EOA = 0xcC06464C7bbCF81417c08563dA2E1847c22b703a; - address private constant ASSET_EOA = 0x1bae1083cf4125ed5deeb778985c1effac0ecc06; - - // team member addresses - address private constant DUNKS = 0x069e85d4f1010dd961897dc8c095fbb5ff297434; - address private constant T0RB1K = 0x0b776552c1aef1dc33005dd25acda22493b6615d; - address private constant CEAZOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; - address private constant MOTTO = 0x78e801136f77805239a7f533521a7a5570f572c8; - address private constant COOLIE = 0x03b88dacb7c21b54cefecc297d981e5b721a9df1; - - // token amounts - uint256 private constant ONE_MILLION = 1e24; // 1e24 == 1e6 (1m) ** 1e18 (decimals) - uint256 private constant TWO_MILLION = 2e24; // 2e24 == 1e6 (1m) ** 1e18 (decimals) - uint256 private constant FOUR_MILLION = 4e24; // 4e24 == 1e6 (1m) ** 1e18 (decimals) - - // time - uint256 private constant ONE_YEAR = 31_536_000; - uint256 private constant TWO_YEARS = 63_072_000; - uint256 private constant FOUR_YEARS = 126_144_000; - function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); @@ -133,103 +112,6 @@ contract Deployment is Script { whitelistedTokens[0] = address(flow); voter.initialize(whitelistedTokens, address(minter)); - // Mint tokens and lock for veNFT - - // 1. Mint to Flow voter EOA - Minter.Claim[] memory flowVoterEOAClaim1 = new Minter.Claim[](4); - for (uint256 i; i < flowVoterEOAClaim1.length; i++) { - flowVoterEOAClaim1[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: ONE_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(flowVoterEOAClaim1, ONE_MILLION * 5); - - Minter.Claim[] memory flowVoterEOAClaim2 = new Minter.Claim[](5); - for (uint256 i; i < flowVoterEOAClaim2.length; i++) { - flowVoterEOAClaim2[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: TWO_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(flowVoterEOAClaim2, TWO_MILLION * 5); - - Minter.Claim[] memory flowVoterEOAClaim3 = new Minter.Claim[](3); - for (uint256 i; i < flowVoterEOAClaim3.length; i++) { - flowVoterEOAClaim3[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(flowVoterEOAClaim3, FOUR_MILLION * 3); - - // 2. Mint to team members - Minter.Claim[] memory dunksClaim = new Minter.Claim[](1); - dunksClaim[0] = Minter.Claim({claimant: DUNKS, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - minter.initialMintAndLock(dunksClaim, FOUR_MILLION); - - Minter.Claim[] memory t0rb1kClaim = new Minter.Claim[](3); - for (uint256 i; i < t0rb1kClaim.length; i++) { - t0rb1kClaim[i] = Minter.Claim({claimant: T0RB1K, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(t0rb1kClaim, FOUR_MILLION * 3); - - Minter.Claim[] memory ceazorClaim = new Minter.Claim[](3); - for (uint256 i; i < ceazorClaim.length; i++) { - ceazorClaim[i] = Minter.Claim({claimant: CEAZOR, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(ceazorClaim, FOUR_MILLION * 3); - - Minter.Claim[] memory mottoClaim = new Minter.Claim[](3); - for (uint256 i; i < mottoClaim.length; i++) { - mottoClaim[i] = Minter.Claim({claimant: MOTTO, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(mottoClaim, FOUR_MILLION * 3); - - Minter.Claim[] memory coolieClaim = new Minter.Claim[](3); - for (uint256 i; i < coolieClaim.length; i++) { - coolieClaim[i] = Minter.Claim({claimant: COOLIE, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(coolieClaim, FOUR_MILLION * 3); - - // 3. Mint to snapshotted veNFT holders - - // 4. Mint for future partners - Minter.Claim[] memory assetEOAClaim1 = new Minter.Claim[](3); - for (uint256 i; i < assetEOAClaim1.length; i++) { - assetEOAClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(assetEOAClaim1, FOUR_MILLION * 3); - - Minter.Claim[] memory multiSigClaim1 = new Minter.Claim[](14); - for (uint256 i; i < multiSigClaim1.length; i++) { - multiSigClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(multiSigClaim1, FOUR_MILLION * 14); - - Minter.Claim[] memory assetEOAClaim2 = new Minter.Claim[](3); - for (uint256 i; i < assetEOAClaim2.length; i++) { - assetEOAClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(assetEOAClaim1, TWO_MILLION * 3); - - Minter.Claim[] memory multiSigClaim2 = new Minter.Claim[](15); - for (uint256 i; i < multiSigClaim2.length; i++) { - multiSigClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(multiSigClaim2, TWO_MILLION * 15); - - Minter.Claim[] memory multiSigClaim3 = new Minter.Claim[](16); - for (uint256 i; i < multiSigClaim3.length; i++) { - multiSigClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(multiSigClaim3, ONE_MILLION * 16); - - Minter.Claim[] memory assetEOAClaim3 = new Minter.Claim[](5); - for (uint256 i; i < assetEOAClaim3.length; i++) { - assetEOAClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: TWO_YEARS}); - } - minter.initialMintAndLock(assetEOAClaim3, ONE_MILLION * 5); - - Minter.Claim[] memory assetEOAClaim4 = new Minter.Claim[](5); - for (uint256 i; i < assetEOAClaim4.length; i++) { - assetEOAClaim4[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: ONE_YEAR}); - } - minter.initialMintAndLock(assetEOAClaim4, ONE_MILLION * 5); - - minter.startActivePeriod(); - vm.stopBroadcast(); } } diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol new file mode 100644 index 00000000..5f84963d --- /dev/null +++ b/scripts/InitialMintAndLock.s.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +// Scripting tool +import {Script} from "../lib/forge-std/src/Script.sol"; + +import {Minter} from "../contracts/Minter.sol"; + +contract InitialMintAndLock is Script { + address private constant TEAM_MULTI_SIG = 0x13eeB8EdfF60BbCcB24Ec7Dd5668aa246525Dc51; + + // address to receive veNFT to be distributed to partners in the future + address private constant FLOW_VOTER_EOA = 0xcC06464C7bbCF81417c08563dA2E1847c22b703a; + address private constant ASSET_EOA = 0x1bae1083cf4125ed5deeb778985c1effac0ecc06; + + // team member addresses + address private constant DUNKS = 0x069e85d4f1010dd961897dc8c095fbb5ff297434; + address private constant T0RB1K = 0x0b776552c1aef1dc33005dd25acda22493b6615d; + address private constant CEAZOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; + address private constant MOTTO = 0x78e801136f77805239a7f533521a7a5570f572c8; + address private constant COOLIE = 0x03b88dacb7c21b54cefecc297d981e5b721a9df1; + + // token amounts + uint256 private constant ONE_MILLION = 1e24; // 1e24 == 1e6 (1m) ** 1e18 (decimals) + uint256 private constant TWO_MILLION = 2e24; // 2e24 == 1e6 (1m) ** 1e18 (decimals) + uint256 private constant FOUR_MILLION = 4e24; // 4e24 == 1e6 (1m) ** 1e18 (decimals) + + // time + uint256 private constant ONE_YEAR = 31_536_000; + uint256 private constant TWO_YEARS = 63_072_000; + uint256 private constant FOUR_YEARS = 126_144_000; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + vm.startBroadcast(deployerPrivateKey); + + // TODO: Fill address after mainnet deploy + Minter minter = Minter(address(0)); + + // Mint tokens and lock for veNFT + + // 1. Mint to Flow voter EOA + Minter.Claim[] memory flowVoterEOAClaim1 = new Minter.Claim[](5); + for (uint256 i; i < flowVoterEOAClaim1.length; i++) { + flowVoterEOAClaim1[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: ONE_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(flowVoterEOAClaim1, ONE_MILLION * flowVoterEOAClaim1.length); + + Minter.Claim[] memory flowVoterEOAClaim2 = new Minter.Claim[](5); + for (uint256 i; i < flowVoterEOAClaim2.length; i++) { + flowVoterEOAClaim2[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: TWO_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(flowVoterEOAClaim2, TWO_MILLION * flowVoterEOAClaim2.length); + + Minter.Claim[] memory flowVoterEOAClaim3 = new Minter.Claim[](3); + for (uint256 i; i < flowVoterEOAClaim3.length; i++) { + flowVoterEOAClaim3[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(flowVoterEOAClaim3, FOUR_MILLION * flowVoterEOAClaim3.length); + + // 2. Mint to team members + Minter.Claim[] memory dunksClaim = new Minter.Claim[](1); + dunksClaim[0] = Minter.Claim({claimant: DUNKS, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + minter.initialMintAndLock(dunksClaim, FOUR_MILLION); + + Minter.Claim[] memory t0rb1kClaim = new Minter.Claim[](3); + for (uint256 i; i < t0rb1kClaim.length; i++) { + t0rb1kClaim[i] = Minter.Claim({claimant: T0RB1K, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(t0rb1kClaim, FOUR_MILLION * t0rb1kClaim.length); + + Minter.Claim[] memory ceazorClaim = new Minter.Claim[](3); + for (uint256 i; i < ceazorClaim.length; i++) { + ceazorClaim[i] = Minter.Claim({claimant: CEAZOR, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(ceazorClaim, FOUR_MILLION * ceazorClaim.length); + + Minter.Claim[] memory mottoClaim = new Minter.Claim[](3); + for (uint256 i; i < mottoClaim.length; i++) { + mottoClaim[i] = Minter.Claim({claimant: MOTTO, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(mottoClaim, FOUR_MILLION * mottoClaim.length); + + Minter.Claim[] memory coolieClaim = new Minter.Claim[](3); + for (uint256 i; i < coolieClaim.length; i++) { + coolieClaim[i] = Minter.Claim({claimant: COOLIE, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(coolieClaim, FOUR_MILLION * coolieClaim.length); + + // 3. TODO: Mint to snapshotted veNFT holders + + // 4. Mint for future partners + Minter.Claim[] memory assetEOAClaim1 = new Minter.Claim[](3); + for (uint256 i; i < assetEOAClaim1.length; i++) { + assetEOAClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(assetEOAClaim1, FOUR_MILLION * assetEOAClaim1.length); + + Minter.Claim[] memory multiSigClaim1 = new Minter.Claim[](13); + for (uint256 i; i < multiSigClaim1.length; i++) { + multiSigClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(multiSigClaim1, FOUR_MILLION * multiSigClaim1.length); + + Minter.Claim[] memory assetEOAClaim2 = new Minter.Claim[](3); + for (uint256 i; i < assetEOAClaim2.length; i++) { + assetEOAClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(assetEOAClaim1, TWO_MILLION * assetEOAClaim2.length); + + Minter.Claim[] memory multiSigClaim2 = new Minter.Claim[](15); + for (uint256 i; i < multiSigClaim2.length; i++) { + multiSigClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(multiSigClaim2, TWO_MILLION * multiSigClaim2.length); + + Minter.Claim[] memory multiSigClaim3 = new Minter.Claim[](16); + for (uint256 i; i < multiSigClaim3.length; i++) { + multiSigClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); + } + minter.initialMintAndLock(multiSigClaim3, ONE_MILLION * multiSigClaim3.length); + + Minter.Claim[] memory assetEOAClaim3 = new Minter.Claim[](5); + for (uint256 i; i < assetEOAClaim3.length; i++) { + assetEOAClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: TWO_YEARS}); + } + minter.initialMintAndLock(assetEOAClaim3, ONE_MILLION * assetEOAClaim3.length); + + Minter.Claim[] memory assetEOAClaim4 = new Minter.Claim[](5); + for (uint256 i; i < assetEOAClaim4.length; i++) { + assetEOAClaim4[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: ONE_YEAR}); + } + minter.initialMintAndLock(assetEOAClaim4, ONE_MILLION * assetEOAClaim4.length); + + // set initializer to 0 so we can no longer mint more + minter.startActivePeriod(); + + vm.stopBroadcast(); + } +} From b209f2286f8c77efce7ad485d72f036a73749580 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:44:19 +0000 Subject: [PATCH 076/156] build: Update initial weekly emission to 13m --- contracts/Minter.sol | 2 +- test/Minter.t.sol | 8 ++++---- test/MinterTeamEmissions.t.sol | 8 ++++---- test/VeloVoting.t.sol | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/contracts/Minter.sol b/contracts/Minter.sol index e5f9e041..88bd1cb5 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -20,7 +20,7 @@ contract Minter is IMinter { IVoter public immutable _voter; IVotingEscrow public immutable _ve; IRewardsDistributor public immutable _rewards_distributor; - uint public weekly = 15_000_000 * 1e18; // represents a starting weekly emission of 15M FLOW (FLOW has 18 decimals) + uint public weekly = 13_000_000 * 1e18; // represents a starting weekly emission of 13M FLOW (FLOW has 18 decimals) uint public active_period; uint internal constant LOCK = 86400 * 7 * 52 * 4; diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 39a8f1c0..a645ad6b 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -88,13 +88,13 @@ contract MinterTest is BaseTest { initializeVotingEscrow(); minter.update_period(); - assertEq(minter.weekly(), 15 * TOKEN_1M); // 15M + assertEq(minter.weekly(), 13 * TOKEN_1M); // 13M _elapseOneWeek(); minter.update_period(); assertEq(distributor.claimable(1), 0); - assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift + assertLt(minter.weekly(), 13 * TOKEN_1M); // <13M for week shift _elapseOneWeek(); @@ -102,13 +102,13 @@ contract MinterTest is BaseTest { uint256 claimable = distributor.claimable(1); /** * This has been updated from 128115516517529 to - * 197073360700 because originally in VELO the + * 170796912607 because originally in VELO the * constructor mints 0 tokens, but now we are minting * an initial supply instead of using the initialMint * function. */ - assertGt(claimable, 197073360700); + assertGt(claimable, 170796912607); distributor.claim(1); assertEq(distributor.claimable(1), 0); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index 9a0f9a5f..a7ea4b6b 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -91,25 +91,25 @@ contract MinterTeamEmissions is BaseTest { amount: TOKEN_1M, lockTime: 86400 * 7 * 52 * 4 }); - minter.initialMintAndLock(claims, 15 * TOKEN_1M); + minter.initialMintAndLock(claims, 13 * TOKEN_1M); minter.startActivePeriod(); assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); - assertEq(FLOW.balanceOf(address(minter)), 14 * TOKEN_1M); + assertEq(FLOW.balanceOf(address(minter)), 12 * TOKEN_1M); uint256 before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 1 uint256 after_ = FLOW.balanceOf(address(owner)); - assertEq(minter.weekly(), 15 * TOKEN_1M); + assertEq(minter.weekly(), 13 * TOKEN_1M); assertEq(after_ - before, 0); vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 2 after_ = FLOW.balanceOf(address(owner)); - assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift + assertLt(minter.weekly(), 13 * TOKEN_1M); // <13M for week shift } function testChangeTeam() public { diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 3bcd3dcb..4c9fe537 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -93,25 +93,25 @@ contract VeloVotingTest is BaseTest { amount: TOKEN_1M, lockTime: 86400 * 7 * 52 * 4 }); - minter.initialMintAndLock(claims, 15 * TOKEN_1M); + minter.initialMintAndLock(claims, 13 * TOKEN_1M); minter.startActivePeriod(); assertEq(escrow.ownerOf(2), address(owner)); assertEq(escrow.ownerOf(3), address(0)); vm.roll(block.number + 1); - assertEq(FLOW.balanceOf(address(minter)), 14 * TOKEN_1M); + assertEq(FLOW.balanceOf(address(minter)), 12 * TOKEN_1M); uint256 before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 1 uint256 after_ = FLOW.balanceOf(address(owner)); - assertEq(minter.weekly(), 15 * TOKEN_1M); + assertEq(minter.weekly(), 13 * TOKEN_1M); assertEq(after_ - before, 0); vm.warp(block.timestamp + ONE_WEEK); vm.roll(block.number + 1); before = FLOW.balanceOf(address(owner)); minter.update_period(); // initial period week 2 after_ = FLOW.balanceOf(address(owner)); - assertLt(minter.weekly(), 15 * TOKEN_1M); // <15M for week shift + assertLt(minter.weekly(), 13 * TOKEN_1M); // <13m for week shift } // Note: _vote and _reset are not included in one-vote-per-epoch From 8ab83e7bce94122ba12abfcf5b758a5509b98884 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:52:52 +0000 Subject: [PATCH 077/156] build: Team member vesting --- contracts/FlowVestor.sol | 2 +- scripts/TeamMemberVesting.s.sol | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 scripts/TeamMemberVesting.s.sol diff --git a/contracts/FlowVestor.sol b/contracts/FlowVestor.sol index 2ee2f53d..8c835ba2 100644 --- a/contracts/FlowVestor.sol +++ b/contracts/FlowVestor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT AND AGPL-3.0-or-later -pragma solidity ^0.8.0; +pragma solidity 0.8.13; import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; diff --git a/scripts/TeamMemberVesting.s.sol b/scripts/TeamMemberVesting.s.sol new file mode 100644 index 00000000..c0f53855 --- /dev/null +++ b/scripts/TeamMemberVesting.s.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +// Scripting tool +import {Script} from "../lib/forge-std/src/Script.sol"; + +import {FlowVestor} from "../contracts/FlowVestor.sol"; +import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; + +contract TeamMemberVesting is Script { + address private constant TEAM_MULTI_SIG = 0x13eeB8EdfF60BbCcB24Ec7Dd5668aa246525Dc51; + + // team member addresses + address private constant T0RB1K = 0x0b776552c1aef1dc33005dd25acda22493b6615d; + address private constant MOTTO = 0x78e801136f77805239a7f533521a7a5570f572c8; + address private constant COOLIE = 0x03b88dacb7c21b54cefecc297d981e5b721a9df1; + + address private constant ADMIN = 0xBC3043983276887f6b6F164Df33646479C9b1653; + // TODO: Fill the address + address private constant FLOW = 0x0000000000000000000000000000000000000000; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + vm.startBroadcast(deployerPrivateKey); + + FlowVestor flowVestor = new FlowVestor(ADMIN, FLOW); + + IERC20(FLOW).approve(address(flowVestor), 4_500_000e18); + flowVestor.vestFor(T0RB1K, 2_000_000e18); + flowVestor.vestFor(MOTTO, 2_000_000e18); + flowVestor.vestFor(COOLIE, 500_000e18); + + flowVestor.transferOwnership(TEAM_MULTI_SIG); + + IERC20(FLOW).transfer(TEAM_MULTI_SIG, 2_500_000e18); + + vm.stopBroadcast(); + } +} From b97e150220f53d7e74f2792ce631a1cf663dc24c Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:57:02 +0000 Subject: [PATCH 078/156] build: Flow convertor deployment --- scripts/FlowConvertorDeployment.s.sol | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 scripts/FlowConvertorDeployment.s.sol diff --git a/scripts/FlowConvertorDeployment.s.sol b/scripts/FlowConvertorDeployment.s.sol new file mode 100644 index 00000000..0f70373c --- /dev/null +++ b/scripts/FlowConvertorDeployment.s.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +// Scripting tool +import {Script} from "../lib/forge-std/src/Script.sol"; + +import {FlowConvertor} from "../contracts/FlowConvertor.sol"; + +contract FlowConvertorDeployment is Script { + address private constant TEAM_MULTI_SIG = 0x13eeB8EdfF60BbCcB24Ec7Dd5668aa246525Dc51; + // TODO: Fill the address + address private constant FLOW = 0x0000000000000000000000000000000000000000; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + vm.startBroadcast(deployerPrivateKey); + + FlowVestor flowConvertor = new flowConvertor({_v1: 0x2baec546a92ca3469f71b7a091f7df61e5569889, _v2: FLOW}); + + flowVestor.transferOwnership(TEAM_MULTI_SIG); + + IERC20(FLOW).transfer(address(flowConvertor), 55_000_000e18); + + vm.stopBroadcast(); + } +} From d0ed9fd7625f2cd394a3c8f73c087b5ee021995d Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:58:05 +0000 Subject: [PATCH 079/156] chore: Remove TODO --- scripts/Deployment.s.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index e2b9da2f..abed6278 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -82,7 +82,6 @@ contract Deployment is Script { address(votingEscrow), address(rewardsDistributor) ); - // TODO: Minter.initialize, Minter.setTeam // Set flow minter to contract flow.setMinter(address(minter)); From 1b1426ae6a6f09f7e1ec46ffbac258305eacece8 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 19:58:47 +0000 Subject: [PATCH 080/156] build: PairFactory set tank --- scripts/Deployment.s.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index abed6278..bb6fbae6 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -86,8 +86,9 @@ contract Deployment is Script { // Set flow minter to contract flow.setMinter(address(minter)); - // Set pair factory pauser + // Set pair factory pauser and tank pairFactory.setPauser(TEAM_MULTI_SIG); + pairFactory.setTank(TANK); // Set voting escrow's voter votingEscrow.setVoter(address(voter)); From 95beaae73d84f94f5dbd845822ca168da6d21715 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 20:00:18 +0000 Subject: [PATCH 081/156] build: Voting escrod set ve art proxy --- scripts/Deployment.s.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index bb6fbae6..a1fd1041 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -90,8 +90,9 @@ contract Deployment is Script { pairFactory.setPauser(TEAM_MULTI_SIG); pairFactory.setTank(TANK); - // Set voting escrow's voter + // Set voting escrow's voter and art proxy votingEscrow.setVoter(address(voter)); + votingEscrow.setArtProxy(address(veArtProxy)); // Set minter and voting escrow's team votingEscrow.setTeam(TEAM_MULTI_SIG); From 323497e0fe4471d7cb5980362c34dc5ededbc32a Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 20:02:28 +0000 Subject: [PATCH 082/156] build: Pair factory set X --- scripts/Deployment.s.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index a1fd1041..568bd32c 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -97,6 +97,10 @@ contract Deployment is Script { // Set minter and voting escrow's team votingEscrow.setTeam(TEAM_MULTI_SIG); minter.setTeam(TEAM_MULTI_SIG); + pairFactory.setTeam(TEAM_MULTI_SIG); + + // Set fee manager + pairFactory.setFeeManager(TEAM_MULTI_SIG); // Set voter's governor voter.setGovernor(TEAM_MULTI_SIG); From b3da29b28547a60ba6e4d64b2cca249c7205c7fe Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 20:09:36 +0000 Subject: [PATCH 083/156] chore: Initial liquid supply should be 82m --- contracts/Flow.sol | 2 +- test/Minter.t.sol | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/Flow.sol b/contracts/Flow.sol index f9c48e73..97eb5f72 100644 --- a/contracts/Flow.sol +++ b/contracts/Flow.sol @@ -20,7 +20,7 @@ contract Flow is IFlow { constructor(address initialSupplyRecipient) { minter = msg.sender; - _mint(initialSupplyRecipient, 300 * 1e6 * 1e18); + _mint(initialSupplyRecipient, 82 * 1e6 * 1e18); } // No checks as its meant to be once off to set minting rights to BaseV1 Minter diff --git a/test/Minter.t.sol b/test/Minter.t.sol index a645ad6b..1e824dd9 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -102,13 +102,13 @@ contract MinterTest is BaseTest { uint256 claimable = distributor.claimable(1); /** * This has been updated from 128115516517529 to - * 170796912607 because originally in VELO the + * 4368856374421 because originally in VELO the * constructor mints 0 tokens, but now we are minting * an initial supply instead of using the initialMint * function. */ - assertGt(claimable, 170796912607); + assertGt(claimable, 4368856374421); distributor.claim(1); assertEq(distributor.claimable(1), 0); From 5c0a9a5ba03c92cbe31e9919c993334e15561486 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 22:44:00 +0000 Subject: [PATCH 084/156] build: Update whitelisted tokens --- scripts/Deployment.s.sol | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 568bd32c..66e12eef 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -112,9 +112,26 @@ contract Deployment is Script { rewardsDistributor.setDepositor(address(minter)); // Initialize tokens for voter - // TODO: Get all the whitelisted tokens - address[] memory whitelistedTokens = new address[](2); + address[] memory whitelistedTokens = new address[](19); whitelistedTokens[0] = address(flow); + whitelistedTokens[1] = 0x4e71a2e537b7f9d9413d3991d37958c0b5e1e503; // NOTE + whitelistedTokens[2] = 0x80b5a32e4f032b2a058b4f29ec95eefeeb87adcd; // USDC + whitelistedTokens[3] = 0x5db67696c3c088dfbf588d3dd849f44266ff0ffa; // CRE + whitelistedTokens[4] = WCANTO; + whitelistedTokens[5] = 0xeceeefcee421d8062ef8d6b4d814efe4dc898265; // ATOM + whitelistedTokens[6] = 0x1d54ecb8583ca25895c512a8308389ffd581f9c9; // INJ + whitelistedTokens[7] = 0x3452e23f9c4cc62c70b7adad699b264af3549c19; // CMDX + whitelistedTokens[8] = 0xc5e00d3b04563950941f7137b5afa3a534f0d6d6; // KAVA + whitelistedTokens[9] = 0x5ad523d94efb56c400941eb6f34393b84c75ba39; // AKT + whitelistedTokens[10] = 0x0ce35b0d42608ca54eb7bcc8044f7087c18e7717; // OSMO + whitelistedTokens[11] = 0xe832c073b1b665e21150ac70fa7c798d9926ccf1; // WAIT + whitelistedTokens[12] = 0x7264610a66eca758a8ce95cf11ff5741e1fd0455; // cINU + whitelistedTokens[13] = 0xc03345448969dd8c00e9e4a85d2d9722d093af8e; // GRAV + whitelistedTokens[14] = 0xfa3c22c069b9556a4b2f7ece1ee3b467909f4864; // SOMM + whitelistedTokens[15] = 0x38d11b40d2173009adb245b869e90525950ae345; // cBONK + whitelistedTokens[16] = 0x5FD55A1B9FC24967C4dB09C513C3BA0DFa7FF687; // ETH + whitelistedTokens[17] = 0xd567B3d7B8FE3C79a1AD8dA978812cfC4Fa05e75; // USDT + whitelistedTokens[18] = 0x74ccbe53F77b08632ce0CB91D3A545bF6B8E0979; // fBOMB voter.initialize(whitelistedTokens, address(minter)); vm.stopBroadcast(); From dd64cc212427c6cee6bdacd6764cb4384bf7fa23 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 22:55:21 +0000 Subject: [PATCH 085/156] build: Include snapshotted veNFT holders --- scripts/InitialMintAndLock.s.sol | 193 ++++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 1 deletion(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 5f84963d..81d6224f 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -30,13 +30,15 @@ contract InitialMintAndLock is Script { uint256 private constant TWO_YEARS = 63_072_000; uint256 private constant FOUR_YEARS = 126_144_000; + Minter private minter; + function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); vm.startBroadcast(deployerPrivateKey); // TODO: Fill address after mainnet deploy - Minter minter = Minter(address(0)); + minter = Minter(address(0)); // Mint tokens and lock for veNFT @@ -133,9 +135,198 @@ contract InitialMintAndLock is Script { } minter.initialMintAndLock(assetEOAClaim4, ONE_MILLION * assetEOAClaim4.length); + _singleInitialMintAndLock(0xd0cC9738866cd82B237A14c92ac60577602d6c18, 1200000000000000000); + _singleInitialMintAndLock(0x38dAEa6f17E4308b0Da9647dB9ca6D84a3A7E195, 24000000000000000000000); + _singleInitialMintAndLock(0xaA970e6bD6E187492f8327e514c9E8c36c81f11E, 24000000000000000000000); + _singleInitialMintAndLock(0xa66e216b038d0F4121bf9A218dABbf4759375f5E, 1200000000000000000000); + _singleInitialMintAndLock(0xC9eebecb1d0AfF4fb2B9978516E075A33639892C, 1025088000000000000000); + _singleInitialMintAndLock(0xe9335fabfB4536bE78D539D759a29e1AFE7455A6, 3508800000000000000000); + _singleInitialMintAndLock(0x37FC9Dc092E8a30A63A1567C9ac9738A7D4A08ed, 1200000000000000000000); + _singleInitialMintAndLock(0x0496cbAD3B943cc246Aa793AB069bFC5516961Ef, 1200000000000000000000); + _singleInitialMintAndLock(0xaA970e6bD6E187492f8327e514c9E8c36c81f11E, 12000000000000000000000); + _singleInitialMintAndLock(0x3aE6a0e8Ec1Edd305553686387dC85Ff8D16AC51, 1014000000000000000000); + _singleInitialMintAndLock(0xED20BC9f8BE737572d7e40237023C7A8FEA3449e, 61044000000000000000); + _singleInitialMintAndLock(0x6c7286c5AB525ccD92c134c0dCDfDdfcA018B048, 600000000000000000000); + _singleInitialMintAndLock(0x5Be66f4095f89BD18aBE4aE9d2acD5021EC433Bc, 900000000000000000000); + _singleInitialMintAndLock(0xB1fC41Cbad16caFDfC2ED196c7fe515DfB6a1577, 3762240000000000000000); + _singleInitialMintAndLock(0x2Ba838E42126aC349D01c3D1FAc85a36266151a4, 36000000000000000000); + _singleInitialMintAndLock(0x609470c2f08FF626078bA64Ceb905d73b155089d, 840000000000000000000); + _singleInitialMintAndLock(0x947D9bcDc2C34Df8587630CAf45b2a2bf07c88cB, 6000000000000000000000); + _singleInitialMintAndLock(0x82619EDe0ac5d964a0711613cFf5446ED3fF85Dc, 1200000000000000000); + _singleInitialMintAndLock(0x707c4603FB72996FF95AB91f571516aFC0F3Fe1b, 70608000000000000000); + _singleInitialMintAndLock(0x7E3b6f966f3666F77813db84DD352173749D24d8, 600000000000000000000); + _singleInitialMintAndLock(0x037B21279931E628b11b4507b9F7870B15dE1C17, 787824000000000000000); + _singleInitialMintAndLock(0x3C2d6d7144241F1F1203c29C124585e55B58975E, 240000000000000000000); + _singleInitialMintAndLock(0x3C2d6d7144241F1F1203c29C124585e55B58975E, 240000000000000000000); + _singleInitialMintAndLock(0xc742a9458c4Cc6f6498007ffC81266Cd3a3f578A, 28800000000000000000); + _singleInitialMintAndLock(0x891C16d225e4Fd30d0874Bf2E139B0c11a459a07, 1351200000000000000000); + _singleInitialMintAndLock(0x5FE1521173F553084eD21e5CbeDE7233b5fE1AA7, 120000000000000000000); + _singleInitialMintAndLock(0x540A6992368aA24dd6baD1DB8BF4982e6183Caf3, 892536000000000000000); + _singleInitialMintAndLock(0x20cE0C0f284219f4E0B68804a8333A782461674c, 30000000000000000000); + _singleInitialMintAndLock(0x41a6ac7f4e4DBfFEB934f95F1Db58B68C76Dc4dF, 43788000000000000000); + _singleInitialMintAndLock(0x9665B6F0CF162792851A902E452248B16F2f4b5A, 1692540023765800000000); + _singleInitialMintAndLock(0x9665B6F0CF162792851A902E452248B16F2f4b5A, 978720000000000000000); + _singleInitialMintAndLock(0x02706C602c59F86Cc2EbD9aE662a25987A7C7986, 198000000000000000000); + _singleInitialMintAndLock(0x5FE1521173F553084eD21e5CbeDE7233b5fE1AA7, 480000000000000000000); + _singleInitialMintAndLock(0x15Eb585735334Db4B0B75919e5990E6391863B39, 34800000000000000000); + _singleInitialMintAndLock(0x96FCa82BB2ce4c5A700a14581412366CC05dd6fA, 3600000000000000000000); + _singleInitialMintAndLock(0xb00d51d3992BC412f783D0e21EDcf952Ce651D91, 1824000000000000000); + _singleInitialMintAndLock(0x56BbBDD8d9e939EC047E3a61907a4caF4d90d231, 4645200000000000000000); + _singleInitialMintAndLock(0x274949b0dB377742A46074f75749E953A8da45A7, 5545200000000000000000); + _singleInitialMintAndLock(0xDc43D0c0497FBf3BB3cf43dcAFaCe9c116d5dd21, 120000000000000000000); + _singleInitialMintAndLock(0xAf79312EB821871208ac76A80c8E282f8796964e, 768000000000000000000); + _singleInitialMintAndLock(0xe4ec13946CE37ae7b3EA6AAC315B486DAD7766F2, 774000000000000000000); + _singleInitialMintAndLock(0xB3dDC2A5B4EbDb7640191906Bd4195E23e17142c, 1800000000000000000000); + _singleInitialMintAndLock(0xb0FabE3bCAC50F065DBF68C0B271118DDC005402, 24000000000000000000000); + _singleInitialMintAndLock(0x6fE4aceD57AE0b50D14229F3d40617C8b7d2F2E1, 2230332000000000000000); + _singleInitialMintAndLock(0xd264bC31A13D962c22967f02e44DAdD8Bbf25232, 240000000000000000000); + _singleInitialMintAndLock(0xbFB5458071867Bc00985BC6c13EE400327Ac5F97, 60000000000000000000); + _singleInitialMintAndLock(0x56F662AADe12e5aB99C4dcb037d1274d0d5dcb94, 29897047241334700000000); + _singleInitialMintAndLock(0x3a390b018fc3425d06FB84DCcdD140481A960939, 2452800000000000000000); + _singleInitialMintAndLock(0xCb59280EB3983a4221263343EF184D2D0189De17, 158400000000000000000); + _singleInitialMintAndLock(0x0d7BbDb6d0D82E896ECB8ED8Bc33aaBd20dE0dA9, 3506400000000000000000); + _singleInitialMintAndLock(0x2ed284077cc25A3f400DAEA79714Ac4A5AC474aC, 613200000000000000000); + _singleInitialMintAndLock(0x14989473630F117Dd5583B946B9B4733CD305e57, 6741600000000000000000); + _singleInitialMintAndLock(0x6f5a8A35fb10EEcEF9128f407a0fe67B898556CF, 12554198211802100000000); + _singleInitialMintAndLock(0x812B9c3Ea2c49beC95D0Bcda4Db39513baaee261, 1789008000000000000000); + _singleInitialMintAndLock(0x80bb0D87DCe1a94329586Ce9C7d39692bBf44af6, 1200000000000000000000); + _singleInitialMintAndLock(0x80bb0D87DCe1a94329586Ce9C7d39692bBf44af6, 120000000000000000000); + _singleInitialMintAndLock(0x30B5a6e6f54507E0DEE280923234204B6A82664A, 195492000000000000000); + _singleInitialMintAndLock(0x2e0692A3d9097931E9b7ba47035C8EA4A388f747, 7044000000000000000000); + _singleInitialMintAndLock(0x57702217d1cDbf4DF7110ABD91832216310B4062, 1200000000000000000000); + _singleInitialMintAndLock(0x09bAc567D73E8BC701a900D14C90c06644eA0156, 885600000000000000000); + _singleInitialMintAndLock(0x4A228f14d2130E8E4636418B52aAF3D6b4E887D3, 4382400000000000000000); + _singleInitialMintAndLock(0xd8b87A01980eB792e3BC030bDEc42Db2b9B5CBfc, 241200000000000000000); + _singleInitialMintAndLock(0x25217b4A6138350350A2ce1f97A6B0111bbFdB56, 1200000000000000000000); + _singleInitialMintAndLock(0x973872cA85cD7175b02FE24701438174901ED751, 1560000000000000000000); + _singleInitialMintAndLock(0xB0720A40d6335dF0aC90fF9e4b755217632Ca78C, 1488000000000000000000); + _singleInitialMintAndLock(0x3AA6605d87f611E43aD0a64740d6BeF9b80FCD2C, 6000000000000000000000); + _singleInitialMintAndLock(0x135Cc51c0b07a8f70256e8DF398e6B916b402444, 360000000000000000000); + _singleInitialMintAndLock(0x945a873B0E08a361458141f637031490cA01b9c1, 576000000000000000000); + _singleInitialMintAndLock(0x464F6392E68Bc6093354E5bf12692e37F5e4113e, 1200000000000000000000); + _singleInitialMintAndLock(0x1C86E98A4CC451db8A502f31c14327D2B7CEC123, 339532320000000000000); + _singleInitialMintAndLock(0x17114903eB90909D3058dAE24D583E5970030FFb, 5400000000000000000000); + _singleInitialMintAndLock(0x17114903eB90909D3058dAE24D583E5970030FFb, 3829200000000000000000); + _singleInitialMintAndLock(0xe12D731750E222eC53b001E00d978901B134CFC9, 332400000000000000000); + _singleInitialMintAndLock(0x801612E860e40612cfbbdEF0133A2Fb6938f2f73, 48000000000000000000); + _singleInitialMintAndLock(0xe12D731750E222eC53b001E00d978901B134CFC9, 2145600000000000000000); + _singleInitialMintAndLock(0xE7A1C621Ed75EC40fe4c86605e60d2851287D14D, 146400000000000000000); + _singleInitialMintAndLock(0xD1A0B66835D830e9ada42eEf436f3AA8005b20B5, 1896000000000000000000); + _singleInitialMintAndLock(0x7Cb552152e2b28F9f6911c51B69B0d8D1FADafe1, 96000000000000000000); + _singleInitialMintAndLock(0x249A49d3201C1B92a1029Aab1BC76a6Ca8f5FFf0, 248400000000000000000); + _singleInitialMintAndLock(0xc27FD9D5113dE19EA89D0265Be9FD93F35f052c8, 2341200000000000000000); + _singleInitialMintAndLock(0xf6301E682769A8b3ECdCe94b2419ba40A958D17e, 3085080000000000000000); + _singleInitialMintAndLock(0xfe5a2B6Cf60e8A5c06a87c999E7944421653e0f3, 240000000000000000000); + _singleInitialMintAndLock(0x0D0d6625F9A0B3370b4b69393E59fdD4d077BB38, 784800000000000000000); + _singleInitialMintAndLock(0xbC82A7232c1f043e4cc608e0eC1510Cf50E28f64, 108000000000000000000); + _singleInitialMintAndLock(0x35128c4263aA0213c59A897Fd31d8C837E8B71C8, 120000000000000000000); + _singleInitialMintAndLock(0x7Cb552152e2b28F9f6911c51B69B0d8D1FADafe1, 12000000000000000000); + _singleInitialMintAndLock(0xDE0187458364Eb836D5bF563721efD1ED14B9673, 240000000000000000000); + _singleInitialMintAndLock(0x0a3043F9d2b1c6cCfc492EB59Af5156F378c57BD, 1200000000000000000); + _singleInitialMintAndLock(0xAE886e2A6AA00e98C0C7b1e4885f94a2dB720690, 6240696000000000000000); + _singleInitialMintAndLock(0x5fA275BA9F04BDC906084478Dbf41CBE29388C5d, 112800000000000000000); + _singleInitialMintAndLock(0x97294B51BF128E6988c7747E0696Ed7F7CfEe993, 1856040000000000000000); + _singleInitialMintAndLock(0x945a873B0E08a361458141f637031490cA01b9c1, 805200000000000000000); + _singleInitialMintAndLock(0x865D7eb5db37cc02ec209DD778f4e3851a421A20, 329760000000000000000); + _singleInitialMintAndLock(0x97c98D6ab8DBbfe6ba464BD7a849d376DA1bB540, 180000000000000000000); + _singleInitialMintAndLock(0x55e1490a1878D0B61811726e2cB96560022E764c, 86880000000000000000); + _singleInitialMintAndLock(0x97Db0E57b1C315a08cc889Ed405ADB100D7F137d, 1327116000000000000000); + _singleInitialMintAndLock(0xc45D05CDc809d20c7B14959E8cd4a1199E3e966F, 1419144000000000000000); + _singleInitialMintAndLock(0xEfce38f31Ebeb9637E85D3487595261FDf6ebeEb, 174600000000000000000); + _singleInitialMintAndLock(0x5A1a3dff949225E39767Ca981218756DB47C7d8c, 60000000000000000000); + _singleInitialMintAndLock(0xd286a9bB11d2165915E3bf6D1c79aadEBe30f605, 90900000000000000000); + _singleInitialMintAndLock(0xBd1E1Cc9613B510d1669D1e79Fd0115C70a4C7be, 480000000000000000000); + _singleInitialMintAndLock(0xBd1E1Cc9613B510d1669D1e79Fd0115C70a4C7be, 547200000000000000000); + _singleInitialMintAndLock(0xC438E5d32f9381b59072b9a0c730Cbac41575A4E, 6000000000000000000000); + _singleInitialMintAndLock(0x1E480827489E3eA19f82EF213b67200A76C0DF58, 360000000000000000000); + _singleInitialMintAndLock(0x0D69BF20A4A00cbebC569E4beF27a78DcB4C0880, 240000000000000000000); + _singleInitialMintAndLock(0x1E480827489E3eA19f82EF213b67200A76C0DF58, 1492800000000000000000); + _singleInitialMintAndLock(0x908E8E8084d660f8f9054AA8Ad1B31380d04B08F, 85572000000000000000); + _singleInitialMintAndLock(0xdDb3e886D78F180A0B435741901cE091cdd0a848, 1862400000000000000000); + _singleInitialMintAndLock(0x90F15E09B8Fb5BC080B968170C638920Db3A3446, 120000000000000000000000); + _singleInitialMintAndLock(0xbC82A7232c1f043e4cc608e0eC1510Cf50E28f64, 217200000000000000000); + _singleInitialMintAndLock(0x56E30aF541D4d54b96770Ecc1a9113F02FEe3bf1, 18917688000000000000000); + _singleInitialMintAndLock(0x20cE0C0f284219f4E0B68804a8333A782461674c, 30000000000000000000); + _singleInitialMintAndLock(0xd7F1BfBfA430FFEE78511E37772cAdaFF63A9A23, 1200000000000000000); + _singleInitialMintAndLock(0xCba1A275e2D858EcffaF7a87F606f74B719a8A93, 300000000000000000000000); + _singleInitialMintAndLock(0x4A401Ee7Fef089CD20D183fE2510d7BD38294728, 241200000000000000000); + _singleInitialMintAndLock(0xFe36AacBCF5677a4A04288764C16acb4220894b9, 1200000000000000000000); + _singleInitialMintAndLock(0x707c4603FB72996FF95AB91f571516aFC0F3Fe1b, 61398000000000000000); + _singleInitialMintAndLock(0xAA1742ab92c694934b97Ab9F557E565Bd2217BFf, 120000000000000000000); + _singleInitialMintAndLock(0xE524D29daf6D7CDEaaaF07Fa1aa7732a45f330B3, 1080000000000000000000); + _singleInitialMintAndLock(0x8E07Ab8Fc9E5F2613b17a5E5069673d522D0207a, 120000000000000000000); + _singleInitialMintAndLock(0x9DEB607b7E92096df55b02aA563e82F612fD0DEf, 1670256000000000000000); + _singleInitialMintAndLock(0x7798Ba9512B5A684C12e31518923Ea4221A41Fb9, 1712160000000000000000); + _singleInitialMintAndLock(0x868CBfd33ec93B451c510125E4D9f1AB1E42fcD2, 1680396000000000000000); + _singleInitialMintAndLock(0xAB63953B631336bD204fdcF126e2a010A47b1A36, 780000000000000000000); + _singleInitialMintAndLock(0x7074E05C39b41EDd1C16478856b5de54B3ac67D6, 1200000000000000000); + _singleInitialMintAndLock(0x479dE30A1E7e53657C437a6d36ae6389B290B5Fb, 3600000000000000000000); + _singleInitialMintAndLock(0xb8920e475E32B807cE51e0eF823fE070D7D96e8C, 528000000000000000000); + _singleInitialMintAndLock(0xb0916C38861dCeef1A62A77887e573861FFb5d63, 27600000000000000000); + _singleInitialMintAndLock(0x707c4603FB72996FF95AB91f571516aFC0F3Fe1b, 27634800000000000000); + _singleInitialMintAndLock(0xDEb3994785Bfc8863e808df0E0C43C9C0058d7c9, 571440000000000000000); + _singleInitialMintAndLock(0x4CE69fd760AD0c07490178f9a47863Dc0358cCCD, 600000000000000000000); + _singleInitialMintAndLock(0x6F106e0ef498a594CCE8280976822fA3798A35cb, 2429760000000000000000); + _singleInitialMintAndLock(0x9b25235ee2e5564F50810E03eA5F91976A8EE6fA, 4705200000000000000000); + _singleInitialMintAndLock(0xEFa9bEbE299dE7AcAECa6876E1E4f5508eEeF2db, 7200000000000000000); + _singleInitialMintAndLock(0x5fA275BA9F04BDC906084478Dbf41CBE29388C5d, 120000000000000000000); + _singleInitialMintAndLock(0x5fA275BA9F04BDC906084478Dbf41CBE29388C5d, 62400000000000000000); + _singleInitialMintAndLock(0xC9eebecb1d0AfF4fb2B9978516E075A33639892C, 1200000000000000000000); + _singleInitialMintAndLock(0x865D7eb5db37cc02ec209DD778f4e3851a421A20, 364800000000000000000); + _singleInitialMintAndLock(0xd0441C0B63f6c97D56e9490B3fdd1c45F89D3678, 5806800000000000000000); + _singleInitialMintAndLock(0xb0916C38861dCeef1A62A77887e573861FFb5d63, 14400000000000000000); + _singleInitialMintAndLock(0xbA00D84Ddbc8cAe67C5800a52496E47A8CaFcd27, 21493200000000000000000); + _singleInitialMintAndLock(0xD40846A19fdC9c8255DCcD18BcBB261BDBF5e4db, 338040000000000000000); + _singleInitialMintAndLock(0xFe36AacBCF5677a4A04288764C16acb4220894b9, 1200000000000000000000); + _singleInitialMintAndLock(0x4c890Dc20f7D99D0135396A08d07d1518a45a1DD, 1200000000000000000); + _singleInitialMintAndLock(0xbA00D84Ddbc8cAe67C5800a52496E47A8CaFcd27, 19147200000000000000000); + _singleInitialMintAndLock(0xD40846A19fdC9c8255DCcD18BcBB261BDBF5e4db, 2815200000000000000000); + _singleInitialMintAndLock(0x5fA275BA9F04BDC906084478Dbf41CBE29388C5d, 122400000000000000000); + _singleInitialMintAndLock(0xD40846A19fdC9c8255DCcD18BcBB261BDBF5e4db, 978000000000000000000); + _singleInitialMintAndLock(0x9505F160A9a74ad532d674De4F200484e0049b43, 1489680000000000000000); + _singleInitialMintAndLock(0x9505F160A9a74ad532d674De4F200484e0049b43, 1489680000000000000000); + _singleInitialMintAndLock(0xb6fB12999a09eFfdbcC6F60776331eacCc42E539, 60000000000000000000000); + _singleInitialMintAndLock(0xb6fB12999a09eFfdbcC6F60776331eacCc42E539, 60000000000000000000000); + _singleInitialMintAndLock(0x0a3043F9d2b1c6cCfc492EB59Af5156F378c57BD, 14164800000000000000000); + _singleInitialMintAndLock(0xD26eA7412FB75D5E4c8c9F3EE7b1dfFf64440eE8, 31200000000000000000); + _singleInitialMintAndLock(0xDE0187458364Eb836D5bF563721efD1ED14B9673, 6000000000000000000); + _singleInitialMintAndLock(0x859Fc918Cf1322686FeC52A30E4A9eA388DF876D, 12000000000000000000); + _singleInitialMintAndLock(0xe9bCCEd88099FC4aacF78b7c43307E758E1a5382, 1200000000000000000000); + _singleInitialMintAndLock(0x7206BC81E2C52441EEFfE120118aC880f4528dDA, 3049200000000000000000); + _singleInitialMintAndLock(0x1448D297420799a0dEB4bE0C270E8ec310c8E8dD, 4800000000000000000); + _singleInitialMintAndLock(0x75592081D5FC1c38d2da8098dfE535CaDBe39425, 12000000000000000000); + _singleInitialMintAndLock(0x9105F56F58A9cDB0e2DFb8696197CFAF3E45b9F0, 2904000000000000000); + _singleInitialMintAndLock(0x8DE3c3891268502F77DB7E876d727257DEc0F852, 40380000000000000000); + _singleInitialMintAndLock(0x5D8A52e816b7A29789C32dD21A034caDDd2bC750, 60000000000000000000); + _singleInitialMintAndLock(0x7074E05C39b41EDd1C16478856b5de54B3ac67D6, 1200000000000000000); + _singleInitialMintAndLock(0xD016cCF7B485D658E063d2E7CB3Afef94Bf79548, 6000000000000000000); + _singleInitialMintAndLock(0x7A8B83DaC270463895233Bb3932A799c12919f27, 4200000000000000000); + _singleInitialMintAndLock(0xDE0187458364Eb836D5bF563721efD1ED14B9673, 337200000000000000000); + _singleInitialMintAndLock(0xdDb3e886D78F180A0B435741901cE091cdd0a848, 165264000000000000000); + _singleInitialMintAndLock(0x0b776552c1Aef1Dc33005DD25AcDA22493b6615d, 1200120000000000000000); + _singleInitialMintAndLock(0x9BDbdb4A8f7f816C87a67F5281484ED902C6b942, 1800000000000000000); + _singleInitialMintAndLock(0xf4E2152c622260A1f1f8E8B8c4C3C5065165Ce55, 118800000000000000000); + _singleInitialMintAndLock(0xd204Bc46046FC0Cd3f074fF9B3Be7b5C59f0a150, 3475464000000000000000); + _singleInitialMintAndLock(0xD7bb2EeE591CE19A54636600936eAB8a40f5a65C, 9600000000000000000); + _singleInitialMintAndLock(0xEb0CeB1F89D1dd01bDFD2Ff9e145271d8FEEfB00, 192000000000000000000); + _singleInitialMintAndLock(0x686Bd59caE3e78107515E87B2895cCBe27fb7D0A, 1800000000000000000000); + _singleInitialMintAndLock(0xb245A959A3D2608e248239638a240c5FCFE20596, 856800000000000000000); + _singleInitialMintAndLock(0xdDb3e886D78F180A0B435741901cE091cdd0a848, 246396000000000000000); + _singleInitialMintAndLock(0x4A80f927126eC56c1E6773805fFa03A04216b293, 28406400000000000000000); + _singleInitialMintAndLock(0xB1e22281E1BC8Ab83Da1CB138e24aCB004B5a4ca, 3600000000000000000000); + _singleInitialMintAndLock(0x84A51c92a653dc0e6AE11C9D873C55Ee7Af62106, 2113200000000000000); + _singleInitialMintAndLock(0x84A51c92a653dc0e6AE11C9D873C55Ee7Af62106, 2110800000000000000000); + _singleInitialMintAndLock(0x3bE2a617a86DD49Bc8893ca04CEa2e5F444F9c12, 717600000000000000000); + // set initializer to 0 so we can no longer mint more minter.startActivePeriod(); vm.stopBroadcast(); } + + function _singleInitialAndLock(address owner, uint256 amount) private { + Minter.Claim[] memory claim = new Minter.Claim[](1); + claim[0] = Minter.Claim({claimant: owner, amount: amount, lockTime: FOUR_YEARS}); + minter.initialMintAndLock(claim, amount); + } } From e1804b7cf928f02f3d1b91543edadfdd0ade5d64 Mon Sep 17 00:00:00 2001 From: coolie Date: Sat, 4 Mar 2023 23:02:24 +0000 Subject: [PATCH 086/156] refactor: Move batch mint to function --- scripts/InitialMintAndLock.s.sol | 206 ++++++++++++++++++------------- 1 file changed, 117 insertions(+), 89 deletions(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 81d6224f..dc5bd4f8 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -43,97 +43,112 @@ contract InitialMintAndLock is Script { // Mint tokens and lock for veNFT // 1. Mint to Flow voter EOA - Minter.Claim[] memory flowVoterEOAClaim1 = new Minter.Claim[](5); - for (uint256 i; i < flowVoterEOAClaim1.length; i++) { - flowVoterEOAClaim1[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: ONE_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(flowVoterEOAClaim1, ONE_MILLION * flowVoterEOAClaim1.length); - - Minter.Claim[] memory flowVoterEOAClaim2 = new Minter.Claim[](5); - for (uint256 i; i < flowVoterEOAClaim2.length; i++) { - flowVoterEOAClaim2[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: TWO_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(flowVoterEOAClaim2, TWO_MILLION * flowVoterEOAClaim2.length); - - Minter.Claim[] memory flowVoterEOAClaim3 = new Minter.Claim[](3); - for (uint256 i; i < flowVoterEOAClaim3.length; i++) { - flowVoterEOAClaim3[i] = Minter.Claim({claimant: FLOW_VOTER_EOA, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(flowVoterEOAClaim3, FOUR_MILLION * flowVoterEOAClaim3.length); + _batchInitialMintAndLock({ + owner: FLOW_VOTER_EOA, + numberOfVotingEscrow: 5, + amountPerVotingEscrow: ONE_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: FLOW_VOTER_EOA, + numberOfVotingEscrow: 5, + amountPerVotingEscrow: TWO_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: FLOW_VOTER_EOA, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); // 2. Mint to team members - Minter.Claim[] memory dunksClaim = new Minter.Claim[](1); - dunksClaim[0] = Minter.Claim({claimant: DUNKS, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - minter.initialMintAndLock(dunksClaim, FOUR_MILLION); - - Minter.Claim[] memory t0rb1kClaim = new Minter.Claim[](3); - for (uint256 i; i < t0rb1kClaim.length; i++) { - t0rb1kClaim[i] = Minter.Claim({claimant: T0RB1K, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(t0rb1kClaim, FOUR_MILLION * t0rb1kClaim.length); - - Minter.Claim[] memory ceazorClaim = new Minter.Claim[](3); - for (uint256 i; i < ceazorClaim.length; i++) { - ceazorClaim[i] = Minter.Claim({claimant: CEAZOR, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(ceazorClaim, FOUR_MILLION * ceazorClaim.length); - - Minter.Claim[] memory mottoClaim = new Minter.Claim[](3); - for (uint256 i; i < mottoClaim.length; i++) { - mottoClaim[i] = Minter.Claim({claimant: MOTTO, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(mottoClaim, FOUR_MILLION * mottoClaim.length); - - Minter.Claim[] memory coolieClaim = new Minter.Claim[](3); - for (uint256 i; i < coolieClaim.length; i++) { - coolieClaim[i] = Minter.Claim({claimant: COOLIE, amount: FOUR_MILLION, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(coolieClaim, FOUR_MILLION * coolieClaim.length); - - // 3. TODO: Mint to snapshotted veNFT holders - - // 4. Mint for future partners - Minter.Claim[] memory assetEOAClaim1 = new Minter.Claim[](3); - for (uint256 i; i < assetEOAClaim1.length; i++) { - assetEOAClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(assetEOAClaim1, FOUR_MILLION * assetEOAClaim1.length); - - Minter.Claim[] memory multiSigClaim1 = new Minter.Claim[](13); - for (uint256 i; i < multiSigClaim1.length; i++) { - multiSigClaim1[i] = Minter.Claim({amount: FOUR_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(multiSigClaim1, FOUR_MILLION * multiSigClaim1.length); - - Minter.Claim[] memory assetEOAClaim2 = new Minter.Claim[](3); - for (uint256 i; i < assetEOAClaim2.length; i++) { - assetEOAClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: ASSET_EOA, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(assetEOAClaim1, TWO_MILLION * assetEOAClaim2.length); - - Minter.Claim[] memory multiSigClaim2 = new Minter.Claim[](15); - for (uint256 i; i < multiSigClaim2.length; i++) { - multiSigClaim2[i] = Minter.Claim({amount: TWO_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(multiSigClaim2, TWO_MILLION * multiSigClaim2.length); - - Minter.Claim[] memory multiSigClaim3 = new Minter.Claim[](16); - for (uint256 i; i < multiSigClaim3.length; i++) { - multiSigClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: TEAM_MULTI_SIG, lockTime: FOUR_YEARS}); - } - minter.initialMintAndLock(multiSigClaim3, ONE_MILLION * multiSigClaim3.length); - - Minter.Claim[] memory assetEOAClaim3 = new Minter.Claim[](5); - for (uint256 i; i < assetEOAClaim3.length; i++) { - assetEOAClaim3[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: TWO_YEARS}); - } - minter.initialMintAndLock(assetEOAClaim3, ONE_MILLION * assetEOAClaim3.length); - - Minter.Claim[] memory assetEOAClaim4 = new Minter.Claim[](5); - for (uint256 i; i < assetEOAClaim4.length; i++) { - assetEOAClaim4[i] = Minter.Claim({amount: ONE_MILLION, claimant: ASSET_EOA, lockTime: ONE_YEAR}); - } - minter.initialMintAndLock(assetEOAClaim4, ONE_MILLION * assetEOAClaim4.length); + _batchInitialMintAndLock({ + owner: DUNKS, + numberOfVotingEscrow: 1, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: T0RB1K, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: CEAZOR, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: MOTTO, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: COOLIE, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + // 3. Mint for future partners + _batchInitialMintAndLock({ + owner: ASSET_EOA, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: TEAM_MULTI_SIG, + numberOfVotingEscrow: 13, + amountPerVotingEscrow: FOUR_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: TEAM_MULTI_SIG, + numberOfVotingEscrow: 3, + amountPerVotingEscrow: TWO_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: TEAM_MULTI_SIG, + numberOfVotingEscrow: 15, + amountPerVotingEscrow: TWO_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: TEAM_MULTI_SIG, + numberOfVotingEscrow: 16, + amountPerVotingEscrow: ONE_MILLION, + lockTime: FOUR_YEARS + }); + + _batchInitialMintAndLock({ + owner: ASSET_EOA, + numberOfVotingEscrow: 5, + amountPerVotingEscrow: ONE_MILLION, + lockTime: TWO_YEARS + }); + + _batchInitialMintAndLock({ + owner: ASSET_EOA, + numberOfVotingEscrow: 5, + amountPerVotingEscrow: ONE_MILLION, + lockTime: ONE_YEARS + }); _singleInitialMintAndLock(0xd0cC9738866cd82B237A14c92ac60577602d6c18, 1200000000000000000); _singleInitialMintAndLock(0x38dAEa6f17E4308b0Da9647dB9ca6D84a3A7E195, 24000000000000000000000); @@ -329,4 +344,17 @@ contract InitialMintAndLock is Script { claim[0] = Minter.Claim({claimant: owner, amount: amount, lockTime: FOUR_YEARS}); minter.initialMintAndLock(claim, amount); } + + function _batchInitialMintAndLock( + address owner, + uint256 numberOfVotingEscrow, + uint256 amountPerVotingEscrow, + uint256 lockTime + ) private { + Minter.Claim[] memory claim = new Minter.Claim[](numberOfVotingEscrow); + for (uint256 i; i < numberOfVotingEscrow; i++) { + claim[i] = Minter.Claim({claimant: owner, amount: amountPerVotingEscrow, lockTime: lockTime}); + } + minter.initialMintAndLock(claim, amountPerVotingEscrow * numberOfVotingEscrow); + } } From e905f94b0f330a104b7a91ca64af4423698db116 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 5 Mar 2023 12:26:40 +0800 Subject: [PATCH 087/156] chore: add initial mint for dunks --- scripts/InitialMintAndLock.s.sol | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index dc5bd4f8..15baf23d 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -72,6 +72,13 @@ contract InitialMintAndLock is Script { lockTime: FOUR_YEARS }); + _batchInitialMintAndLock({ + owner: DUNKS, + numberOfVotingEscrow: 1, + amountPerVotingEscrow: ONE_MILLION, + lockTime: FOUR_YEARS + }); + _batchInitialMintAndLock({ owner: T0RB1K, numberOfVotingEscrow: 3, From d9a7d7a21475bdf41700e7b5a53b50e512896971 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 5 Mar 2023 12:27:40 +0800 Subject: [PATCH 088/156] chore: change multi sig claim veNFT from 13 to 14 --- scripts/InitialMintAndLock.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 15baf23d..51c61531 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -117,7 +117,7 @@ contract InitialMintAndLock is Script { _batchInitialMintAndLock({ owner: TEAM_MULTI_SIG, - numberOfVotingEscrow: 13, + numberOfVotingEscrow: 14, amountPerVotingEscrow: FOUR_MILLION, lockTime: FOUR_YEARS }); From c2b3ecb1ac78f3fbbd3396baca05d2fe5cd9ba10 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 5 Mar 2023 12:28:34 +0800 Subject: [PATCH 089/156] chore: change asset eoa initial mint from 5 to 4 --- scripts/InitialMintAndLock.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 51c61531..00c0232e 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -145,7 +145,7 @@ contract InitialMintAndLock is Script { _batchInitialMintAndLock({ owner: ASSET_EOA, - numberOfVotingEscrow: 5, + numberOfVotingEscrow: 4, amountPerVotingEscrow: ONE_MILLION, lockTime: TWO_YEARS }); From d6bb686954012d493a293a936863801d7c199002 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 5 Mar 2023 14:13:10 +0800 Subject: [PATCH 090/156] chore: amend initial mint --- scripts/InitialMintAndLock.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 00c0232e..98136c46 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -75,7 +75,7 @@ contract InitialMintAndLock is Script { _batchInitialMintAndLock({ owner: DUNKS, numberOfVotingEscrow: 1, - amountPerVotingEscrow: ONE_MILLION, + amountPerVotingEscrow: TWO_MILLION, lockTime: FOUR_YEARS }); From e79169ee529ab23f4feb870bec934899b28afba0 Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 20:46:25 +0000 Subject: [PATCH 091/156] fix: Wrong contract/variable name used --- scripts/FlowConvertorDeployment.s.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/FlowConvertorDeployment.s.sol b/scripts/FlowConvertorDeployment.s.sol index 0f70373c..86a9008d 100644 --- a/scripts/FlowConvertorDeployment.s.sol +++ b/scripts/FlowConvertorDeployment.s.sol @@ -16,9 +16,9 @@ contract FlowConvertorDeployment is Script { vm.startBroadcast(deployerPrivateKey); - FlowVestor flowConvertor = new flowConvertor({_v1: 0x2baec546a92ca3469f71b7a091f7df61e5569889, _v2: FLOW}); + FlowConvertor flowConvertor = new FlowConvertor({_v1: 0x2baec546a92ca3469f71b7a091f7df61e5569889, _v2: FLOW}); - flowVestor.transferOwnership(TEAM_MULTI_SIG); + floeConvertor.transferOwnership(TEAM_MULTI_SIG); IERC20(FLOW).transfer(address(flowConvertor), 55_000_000e18); From 723213cabbe050eb64b5c85db0572c6d3dbdae25 Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 22:11:43 +0000 Subject: [PATCH 092/156] fix: Addresses need to be checksummed --- scripts/Deployment.s.sol | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 66e12eef..adc5d16c 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -19,12 +19,12 @@ import {Minter} from "../contracts/Minter.sol"; contract Deployment is Script { // token addresses - address private constant WCANTO = 0x826551890dc65655a0aceca109ab11abdbd7a07b; + address private constant WCANTO = 0x826551890Dc65655a0Aceca109aB11AbDbD7a07B; // privileged accounts - address private constant COUNCIL = 0x06b16991b53632c2362267579ae7c4863c72fdb8; + address private constant COUNCIL = 0x06b16991B53632C2362267579AE7C4863c72fDb8; address private constant TEAM_MULTI_SIG = 0x13eeB8EdfF60BbCcB24Ec7Dd5668aa246525Dc51; - address private constant GOVERNOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; + address private constant GOVERNOR = 0x06b16991B53632C2362267579AE7C4863c72fDb8; address private constant TANK = 0x0A868fd1523a1ef58Db1F2D135219F0e30CBf7FB; function run() external { @@ -114,21 +114,21 @@ contract Deployment is Script { // Initialize tokens for voter address[] memory whitelistedTokens = new address[](19); whitelistedTokens[0] = address(flow); - whitelistedTokens[1] = 0x4e71a2e537b7f9d9413d3991d37958c0b5e1e503; // NOTE - whitelistedTokens[2] = 0x80b5a32e4f032b2a058b4f29ec95eefeeb87adcd; // USDC - whitelistedTokens[3] = 0x5db67696c3c088dfbf588d3dd849f44266ff0ffa; // CRE + whitelistedTokens[1] = 0x4e71A2E537B7f9D9413D3991D37958c0b5e1e503; // NOTE + whitelistedTokens[2] = 0x80b5a32E4F032B2a058b4F29EC95EEfEEB87aDcd; // USDC + whitelistedTokens[3] = 0x5db67696C3c088DfBf588d3dd849f44266ff0ffa; // CRE whitelistedTokens[4] = WCANTO; - whitelistedTokens[5] = 0xeceeefcee421d8062ef8d6b4d814efe4dc898265; // ATOM - whitelistedTokens[6] = 0x1d54ecb8583ca25895c512a8308389ffd581f9c9; // INJ - whitelistedTokens[7] = 0x3452e23f9c4cc62c70b7adad699b264af3549c19; // CMDX - whitelistedTokens[8] = 0xc5e00d3b04563950941f7137b5afa3a534f0d6d6; // KAVA - whitelistedTokens[9] = 0x5ad523d94efb56c400941eb6f34393b84c75ba39; // AKT - whitelistedTokens[10] = 0x0ce35b0d42608ca54eb7bcc8044f7087c18e7717; // OSMO - whitelistedTokens[11] = 0xe832c073b1b665e21150ac70fa7c798d9926ccf1; // WAIT - whitelistedTokens[12] = 0x7264610a66eca758a8ce95cf11ff5741e1fd0455; // cINU - whitelistedTokens[13] = 0xc03345448969dd8c00e9e4a85d2d9722d093af8e; // GRAV - whitelistedTokens[14] = 0xfa3c22c069b9556a4b2f7ece1ee3b467909f4864; // SOMM - whitelistedTokens[15] = 0x38d11b40d2173009adb245b869e90525950ae345; // cBONK + whitelistedTokens[5] = 0xecEEEfCEE421D8062EF8d6b4D814efe4dc898265; // ATOM + whitelistedTokens[6] = 0x1D54EcB8583Ca25895c512A8308389fFD581F9c9; // INJ + whitelistedTokens[7] = 0x3452e23F9c4cC62c70B7ADAd699B264AF3549C19; // CMDX + whitelistedTokens[8] = 0xC5e00D3b04563950941f7137B5AfA3a534F0D6d6; // KAVA + whitelistedTokens[9] = 0x5aD523d94Efb56C400941eb6F34393b84c75ba39; // AKT + whitelistedTokens[10] = 0x0CE35b0D42608Ca54Eb7bcc8044f7087C18E7717; // OSMO + whitelistedTokens[11] = 0xe832c073b1b665E21150aC70Fa7c798d9926cCf1; // WAIT + whitelistedTokens[12] = 0x7264610A66EcA758A8ce95CF11Ff5741E1fd0455; // cINU + whitelistedTokens[13] = 0xc03345448969Dd8C00e9E4A85d2d9722d093aF8E; // GRAV + whitelistedTokens[14] = 0xFA3C22C069B9556A4B2f7EcE1Ee3B467909f4864; // SOMM + whitelistedTokens[15] = 0x38D11B40D2173009aDB245b869e90525950aE345; // cBONK whitelistedTokens[16] = 0x5FD55A1B9FC24967C4dB09C513C3BA0DFa7FF687; // ETH whitelistedTokens[17] = 0xd567B3d7B8FE3C79a1AD8dA978812cfC4Fa05e75; // USDT whitelistedTokens[18] = 0x74ccbe53F77b08632ce0CB91D3A545bF6B8E0979; // fBOMB From 339515e95554013f8230c9bf87ab745cf8429e58 Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 22:15:08 +0000 Subject: [PATCH 093/156] fix: Unused local variable warning --- scripts/Deployment.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index adc5d16c..aaecae85 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -48,7 +48,7 @@ contract Deployment is Script { Router router = new Router(address(pairFactory), WCANTO); // VelocimeterLibrary - VelocimeterLibrary velocimeterLib = new VelocimeterLibrary(address(router)); + new VelocimeterLibrary(address(router)); // VeArtProxy VeArtProxy veArtProxy = new VeArtProxy(); From 6893d3316c4b8fdc7c2c72348963ec3b72b304ac Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 22:16:02 +0000 Subject: [PATCH 094/156] fix: Duplicated VotingEscrow setVoter --- scripts/Deployment.s.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index aaecae85..bae02048 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -90,8 +90,7 @@ contract Deployment is Script { pairFactory.setPauser(TEAM_MULTI_SIG); pairFactory.setTank(TANK); - // Set voting escrow's voter and art proxy - votingEscrow.setVoter(address(voter)); + // Set voting escrow's art proxy votingEscrow.setArtProxy(address(veArtProxy)); // Set minter and voting escrow's team From 1320a91d9e0e6aa8c1e85d31d705eeafaae34a02 Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 22:21:55 +0000 Subject: [PATCH 095/156] fix: Wrong function name --- scripts/InitialMintAndLock.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 98136c46..aeceb0f3 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -346,7 +346,7 @@ contract InitialMintAndLock is Script { vm.stopBroadcast(); } - function _singleInitialAndLock(address owner, uint256 amount) private { + function _singleInitialMintAndLock(address owner, uint256 amount) private { Minter.Claim[] memory claim = new Minter.Claim[](1); claim[0] = Minter.Claim({claimant: owner, amount: amount, lockTime: FOUR_YEARS}); minter.initialMintAndLock(claim, amount); From 6889f2d5b6c581525a91bdc7fa41934b94cd54e8 Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 22:22:20 +0000 Subject: [PATCH 096/156] fix: Typo --- scripts/InitialMintAndLock.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index aeceb0f3..3b7b43f5 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -154,7 +154,7 @@ contract InitialMintAndLock is Script { owner: ASSET_EOA, numberOfVotingEscrow: 5, amountPerVotingEscrow: ONE_MILLION, - lockTime: ONE_YEARS + lockTime: ONE_YEAR }); _singleInitialMintAndLock(0xd0cC9738866cd82B237A14c92ac60577602d6c18, 1200000000000000000); From 11cb74ee2646c988e48a44be08ba936b9f2bef9f Mon Sep 17 00:00:00 2001 From: coolie Date: Sun, 5 Mar 2023 22:24:06 +0000 Subject: [PATCH 097/156] fix: Addresses need to be checksummed --- scripts/InitialMintAndLock.s.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 3b7b43f5..e0b5b6cb 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -11,14 +11,14 @@ contract InitialMintAndLock is Script { // address to receive veNFT to be distributed to partners in the future address private constant FLOW_VOTER_EOA = 0xcC06464C7bbCF81417c08563dA2E1847c22b703a; - address private constant ASSET_EOA = 0x1bae1083cf4125ed5deeb778985c1effac0ecc06; + address private constant ASSET_EOA = 0x1bAe1083CF4125eD5dEeb778985C1Effac0ecC06; // team member addresses - address private constant DUNKS = 0x069e85d4f1010dd961897dc8c095fbb5ff297434; - address private constant T0RB1K = 0x0b776552c1aef1dc33005dd25acda22493b6615d; - address private constant CEAZOR = 0x06b16991b53632c2362267579ae7c4863c72fdb8; - address private constant MOTTO = 0x78e801136f77805239a7f533521a7a5570f572c8; - address private constant COOLIE = 0x03b88dacb7c21b54cefecc297d981e5b721a9df1; + address private constant DUNKS = 0x069e85D4F1010DD961897dC8C095FBB5FF297434; + address private constant T0RB1K = 0x0b776552c1Aef1Dc33005DD25AcDA22493b6615d; + address private constant CEAZOR = 0x06b16991B53632C2362267579AE7C4863c72fDb8; + address private constant MOTTO = 0x78e801136F77805239A7F533521A7a5570F572C8; + address private constant COOLIE = 0x03B88DacB7c21B54cEfEcC297D981E5b721A9dF1; // token amounts uint256 private constant ONE_MILLION = 1e24; // 1e24 == 1e6 (1m) ** 1e18 (decimals) From 3d78c7ad83247ec06ea012777a4c5191e700e829 Mon Sep 17 00:00:00 2001 From: Ceazor Date: Sun, 5 Mar 2023 20:05:31 -0700 Subject: [PATCH 098/156] Added THREE_MILLIONs = 1% --- scripts/InitialMintAndLock.s.sol | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index e0b5b6cb..3d5b8ece 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -23,6 +23,7 @@ contract InitialMintAndLock is Script { // token amounts uint256 private constant ONE_MILLION = 1e24; // 1e24 == 1e6 (1m) ** 1e18 (decimals) uint256 private constant TWO_MILLION = 2e24; // 2e24 == 1e6 (1m) ** 1e18 (decimals) + uint256 private constant THREE_MILLION = 3e24; // 3e24 == 1e6 (1m) ** 1e18 (decimals) uint256 private constant FOUR_MILLION = 4e24; // 4e24 == 1e6 (1m) ** 1e18 (decimals) // time @@ -52,15 +53,15 @@ contract InitialMintAndLock is Script { _batchInitialMintAndLock({ owner: FLOW_VOTER_EOA, - numberOfVotingEscrow: 5, + numberOfVotingEscrow: 6, amountPerVotingEscrow: TWO_MILLION, lockTime: FOUR_YEARS }); _batchInitialMintAndLock({ owner: FLOW_VOTER_EOA, - numberOfVotingEscrow: 3, - amountPerVotingEscrow: FOUR_MILLION, + numberOfVotingEscrow: 2, + amountPerVotingEscrow: THREE_MILLION, lockTime: FOUR_YEARS }); @@ -110,21 +111,21 @@ contract InitialMintAndLock is Script { // 3. Mint for future partners _batchInitialMintAndLock({ owner: ASSET_EOA, - numberOfVotingEscrow: 3, - amountPerVotingEscrow: FOUR_MILLION, + numberOfVotingEscrow: 4, + amountPerVotingEscrow: THREE_MILLION, lockTime: FOUR_YEARS }); _batchInitialMintAndLock({ owner: TEAM_MULTI_SIG, - numberOfVotingEscrow: 14, - amountPerVotingEscrow: FOUR_MILLION, + numberOfVotingEscrow: 18, + amountPerVotingEscrow: THREE_MILLION, lockTime: FOUR_YEARS }); _batchInitialMintAndLock({ - owner: TEAM_MULTI_SIG, - numberOfVotingEscrow: 3, + owner: ASSET_EOA, + numberOfVotingEscrow: 4, amountPerVotingEscrow: TWO_MILLION, lockTime: FOUR_YEARS }); @@ -156,7 +157,17 @@ contract InitialMintAndLock is Script { amountPerVotingEscrow: ONE_MILLION, lockTime: ONE_YEAR }); - + // Mint for current partners and presale + _singleInitialMintAndLock(0x69224dbA1D77bfe6eA99409aB595d04631D95C22, 1205636240970620000000000); + _singleInitialMintAndLock(0x69224dbA1D77bfe6eA99409aB595d04631D95C22, 1201854505093560000000000); + _singleInitialMintAndLock(0x69224dbA1D77bfe6eA99409aB595d04631D95C22, 1207527108909160000000000); + _singleInitialMintAndLock(0x69224dbA1D77bfe6eA99409aB595d04631D95C22, 1207527108909160000000000); + _singleInitialMintAndLock(0x69224dbA1D77bfe6eA99409aB595d04631D95C22, 1207527108909160000000000); + _singleInitialMintAndLock(0xCFFC6e659DF622e2d41c7A879C76E6d33F37925E, 1207527108909160000000000); + _singleInitialMintAndLock(0xF09d213EE8a8B159C884b276b86E08E26B3bfF75, 5000000000000000000000000); + _singleInitialMintAndLock(0x50149b01f19c2D4A403B1FE4469c117a5cEdb4fc, 1006272590757630000000000); + + // Mint for snapshot recipients, quants already 1.2x _singleInitialMintAndLock(0xd0cC9738866cd82B237A14c92ac60577602d6c18, 1200000000000000000); _singleInitialMintAndLock(0x38dAEa6f17E4308b0Da9647dB9ca6D84a3A7E195, 24000000000000000000000); _singleInitialMintAndLock(0xaA970e6bD6E187492f8327e514c9E8c36c81f11E, 24000000000000000000000); From 8879d2ae19db6103de9ef27b6613dd1f58dc6e77 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Mon, 6 Mar 2023 11:38:45 +0800 Subject: [PATCH 099/156] fix: typo --- scripts/FlowConvertorDeployment.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/FlowConvertorDeployment.s.sol b/scripts/FlowConvertorDeployment.s.sol index 86a9008d..28be5e01 100644 --- a/scripts/FlowConvertorDeployment.s.sol +++ b/scripts/FlowConvertorDeployment.s.sol @@ -18,7 +18,7 @@ contract FlowConvertorDeployment is Script { FlowConvertor flowConvertor = new FlowConvertor({_v1: 0x2baec546a92ca3469f71b7a091f7df61e5569889, _v2: FLOW}); - floeConvertor.transferOwnership(TEAM_MULTI_SIG); + flowConvertor.transferOwnership(TEAM_MULTI_SIG); IERC20(FLOW).transfer(address(flowConvertor), 55_000_000e18); From f76d4dfd96e5e079c7e37fcc00d6c1247e7bb57c Mon Sep 17 00:00:00 2001 From: Ceazor Date: Sun, 5 Mar 2023 21:51:10 -0700 Subject: [PATCH 100/156] double check on mints, --- contracts/Flow.sol | 2 +- scripts/FlowConvertorDeployment.s.sol | 2 +- scripts/InitialMintAndLock.s.sol | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/Flow.sol b/contracts/Flow.sol index 97eb5f72..9d1ab8de 100644 --- a/contracts/Flow.sol +++ b/contracts/Flow.sol @@ -20,7 +20,7 @@ contract Flow is IFlow { constructor(address initialSupplyRecipient) { minter = msg.sender; - _mint(initialSupplyRecipient, 82 * 1e6 * 1e18); + _mint(initialSupplyRecipient, 82800140034502500000000000); } // No checks as its meant to be once off to set minting rights to BaseV1 Minter diff --git a/scripts/FlowConvertorDeployment.s.sol b/scripts/FlowConvertorDeployment.s.sol index 28be5e01..416f42e3 100644 --- a/scripts/FlowConvertorDeployment.s.sol +++ b/scripts/FlowConvertorDeployment.s.sol @@ -20,7 +20,7 @@ contract FlowConvertorDeployment is Script { flowConvertor.transferOwnership(TEAM_MULTI_SIG); - IERC20(FLOW).transfer(address(flowConvertor), 55_000_000e18); + IERC20(FLOW).transfer(address(flowConvertor), 50_000_000e18); vm.stopBroadcast(); } diff --git a/scripts/InitialMintAndLock.s.sol b/scripts/InitialMintAndLock.s.sol index 3d5b8ece..f932b3c8 100644 --- a/scripts/InitialMintAndLock.s.sol +++ b/scripts/InitialMintAndLock.s.sol @@ -132,21 +132,21 @@ contract InitialMintAndLock is Script { _batchInitialMintAndLock({ owner: TEAM_MULTI_SIG, - numberOfVotingEscrow: 15, + numberOfVotingEscrow: 14, amountPerVotingEscrow: TWO_MILLION, lockTime: FOUR_YEARS }); _batchInitialMintAndLock({ owner: TEAM_MULTI_SIG, - numberOfVotingEscrow: 16, + numberOfVotingEscrow: 15, amountPerVotingEscrow: ONE_MILLION, lockTime: FOUR_YEARS }); _batchInitialMintAndLock({ owner: ASSET_EOA, - numberOfVotingEscrow: 4, + numberOfVotingEscrow: 5, amountPerVotingEscrow: ONE_MILLION, lockTime: TWO_YEARS }); From a5b26e8de7b10bb8f34190c805d630ce4d515954 Mon Sep 17 00:00:00 2001 From: Ceazor Date: Sun, 5 Mar 2023 23:53:06 -0700 Subject: [PATCH 101/156] remove WAIT Whitelisting. pool shallow --- scripts/Deployment.s.sol | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index bae02048..8e2b02be 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -123,14 +123,13 @@ contract Deployment is Script { whitelistedTokens[8] = 0xC5e00D3b04563950941f7137B5AfA3a534F0D6d6; // KAVA whitelistedTokens[9] = 0x5aD523d94Efb56C400941eb6F34393b84c75ba39; // AKT whitelistedTokens[10] = 0x0CE35b0D42608Ca54Eb7bcc8044f7087C18E7717; // OSMO - whitelistedTokens[11] = 0xe832c073b1b665E21150aC70Fa7c798d9926cCf1; // WAIT - whitelistedTokens[12] = 0x7264610A66EcA758A8ce95CF11Ff5741E1fd0455; // cINU - whitelistedTokens[13] = 0xc03345448969Dd8C00e9E4A85d2d9722d093aF8E; // GRAV - whitelistedTokens[14] = 0xFA3C22C069B9556A4B2f7EcE1Ee3B467909f4864; // SOMM - whitelistedTokens[15] = 0x38D11B40D2173009aDB245b869e90525950aE345; // cBONK - whitelistedTokens[16] = 0x5FD55A1B9FC24967C4dB09C513C3BA0DFa7FF687; // ETH - whitelistedTokens[17] = 0xd567B3d7B8FE3C79a1AD8dA978812cfC4Fa05e75; // USDT - whitelistedTokens[18] = 0x74ccbe53F77b08632ce0CB91D3A545bF6B8E0979; // fBOMB + whitelistedTokens[11] = 0x7264610A66EcA758A8ce95CF11Ff5741E1fd0455; // cINU + whitelistedTokens[12] = 0xc03345448969Dd8C00e9E4A85d2d9722d093aF8E; // GRAV + whitelistedTokens[13] = 0xFA3C22C069B9556A4B2f7EcE1Ee3B467909f4864; // SOMM + whitelistedTokens[14] = 0x38D11B40D2173009aDB245b869e90525950aE345; // cBONK + whitelistedTokens[15] = 0x5FD55A1B9FC24967C4dB09C513C3BA0DFa7FF687; // ETH + whitelistedTokens[16] = 0xd567B3d7B8FE3C79a1AD8dA978812cfC4Fa05e75; // USDT + whitelistedTokens[17] = 0x74ccbe53F77b08632ce0CB91D3A545bF6B8E0979; // fBOMB voter.initialize(whitelistedTokens, address(minter)); vm.stopBroadcast(); From c79dc86b248b24443a3ee58ffc47483f2494ef6c Mon Sep 17 00:00:00 2001 From: coolie Date: Mon, 6 Mar 2023 23:30:53 +0000 Subject: [PATCH 102/156] feat: Use Ownable for PairFactory --- contracts/Voter.sol | 2 +- contracts/factories/PairFactory.sol | 62 ++++------------------------- scripts/Deployment.s.sol | 6 +-- tasks/deploy/op.ts | 3 -- test/BaseTest.sol | 1 - test/utils/TestOwner.sol | 8 ---- 6 files changed, 10 insertions(+), 72 deletions(-) diff --git a/contracts/Voter.sol b/contracts/Voter.sol index 1f1f6af4..747d9135 100644 --- a/contracts/Voter.sol +++ b/contracts/Voter.sol @@ -98,7 +98,7 @@ contract Voter is IVoter { } function setEmergencyCouncil(address _council) public { - require(msg.sender == emergencyCouncil); + require(msg.sender == governor); emergencyCouncil = _council; } diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 06b12892..26de4a4c 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -3,20 +3,15 @@ pragma solidity 0.8.13; import 'contracts/interfaces/IPairFactory.sol'; import 'contracts/Pair.sol'; +import "openzeppelin-contracts/contracts/access/Ownable.sol"; -contract PairFactory is IPairFactory { +contract PairFactory is IPairFactory, Ownable { bool public isPaused; - address public pauser; - address public pendingPauser; - uint256 public stableFee; uint256 public volatileFee; uint256 public constant MAX_FEE = 50; // 0.5% - address public feeManager; - address public pendingFeeManager; address public voter; - address public team; address public tank; address public deployer; @@ -29,42 +24,27 @@ contract PairFactory is IPairFactory { bool internal _temp; event PairCreated(address indexed token0, address indexed token1, bool stable, address pair, uint); - event TeamSet(address indexed setter, address indexed team); event VoterSet(address indexed setter, address indexed voter); event TankSet(address indexed setter, address indexed tank); - event PauserSet(address indexed setter, address indexed pauser); - event PauserAccepted(address indexed previous, address indexed current); event Paused(address indexed pauser, bool paused); - event FeeManagerSet(address indexed setter, address indexed feeManager); - event FeeManagerAccepted(address indexed previous, address indexed current); event FeeSet(address indexed setter, bool stable, uint256 fee); constructor() { - pauser = msg.sender; - isPaused = false; - feeManager = msg.sender; stableFee = 3; // 0.03% volatileFee = 25; // 0.25% deployer = msg.sender; } - function setTeam(address _team) external { - require(team == address(0), 'The team has already been set.'); - require(msg.sender == deployer, 'Not authorised to set team.'); // might need to set this to deployer?? or just make it - team = _team; - emit TeamSet(msg.sender, _team); - } - function setVoter(address _voter) external { require(voter == address(0), 'The voter has already been set.'); - require(msg.sender == deployer, 'Not authorised to set voter.'); // have to make sure that this can be set to the voter addres during init script + // have to make sure that this can be set to the voter address during init script + require(msg.sender == deployer, 'Not authorised to set voter.'); voter = _voter; emit VoterSet(msg.sender, _voter); } - function setTank(address _tank) external { - require(msg.sender == deployer || msg.sender == team, 'Not authorised to set tank.'); // this should be updateable to team but adding deployer so that init script can run.. + function setTank(address _tank) external onlyOwner { tank = _tank; emit TankSet(msg.sender, _tank); } @@ -73,40 +53,12 @@ contract PairFactory is IPairFactory { return allPairs.length; } - function setPauser(address _pauser) external { - require(msg.sender == pauser); - pendingPauser = _pauser; - emit PauserSet(msg.sender, _pauser); - } - - function acceptPauser() external { - require(msg.sender == pendingPauser); - address prevPauser = pauser; - pauser = pendingPauser; - emit PauserAccepted(prevPauser, msg.sender); - } - - function setPause(bool _state) external { - require(msg.sender == pauser); + function setPause(bool _state) external onlyOwner { isPaused = _state; emit Paused(msg.sender, _state); } - function setFeeManager(address _feeManager) external { - require(msg.sender == feeManager, 'not fee manager'); - pendingFeeManager = _feeManager; - emit FeeManagerSet(msg.sender, _feeManager); - } - - function acceptFeeManager() external { - require(msg.sender == pendingFeeManager, 'not pending fee manager'); - address prevFeeManager = feeManager; - feeManager = pendingFeeManager; - emit FeeManagerAccepted(prevFeeManager, msg.sender); - } - - function setFee(bool _stable, uint256 _fee) external { - require(msg.sender == feeManager, 'not fee manager'); + function setFee(bool _stable, uint256 _fee) external onlyOwner { require(_fee <= MAX_FEE, 'fee too high'); if (_stable) { stableFee = _fee; diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 8e2b02be..9bcd569a 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -87,7 +87,6 @@ contract Deployment is Script { flow.setMinter(address(minter)); // Set pair factory pauser and tank - pairFactory.setPauser(TEAM_MULTI_SIG); pairFactory.setTank(TANK); // Set voting escrow's art proxy @@ -96,10 +95,9 @@ contract Deployment is Script { // Set minter and voting escrow's team votingEscrow.setTeam(TEAM_MULTI_SIG); minter.setTeam(TEAM_MULTI_SIG); - pairFactory.setTeam(TEAM_MULTI_SIG); - // Set fee manager - pairFactory.setFeeManager(TEAM_MULTI_SIG); + // Transfer pair factory ownership to multi-sig + pairFactory.transferOwnership(TEAM_MULTI_SIG); // Set voter's governor voter.setGovernor(TEAM_MULTI_SIG); diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index 488c0867..afff85c7 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -120,9 +120,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( await flow.setMinter(minter.address); console.log("Minter set"); - await pairFactory.setPauser(OP_CONFIG.teamMultisig); - console.log("Pauser set"); - await escrow.setVoter(voter.address); console.log("Voter set"); diff --git a/test/BaseTest.sol b/test/BaseTest.sol index 57b3c2fb..e801ee3a 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.sol @@ -119,7 +119,6 @@ abstract contract BaseTest is Test, TestOwner { assertEq(factory.allPairsLength(), 0); factory.setFee(true, 1); // set fee back to 0.01% for old tests factory.setFee(false, 1); - factory.setTeam(address(msg.sender)); // set team factory.setTank(address(msg.sender)); // set tank router = new Router(address(factory), address(WETH)); diff --git a/test/utils/TestOwner.sol b/test/utils/TestOwner.sol index 7f3ce4ec..5f55f85c 100644 --- a/test/utils/TestOwner.sol +++ b/test/utils/TestOwner.sol @@ -39,14 +39,6 @@ contract TestOwner { PairFactory //////////////////////////////////////////////////////////////*/ - function setFeeManager(address _factory, address _feeManager) public { - PairFactory(_factory).setFeeManager(_feeManager); - } - - function acceptFeeManager(address _factory) public { - PairFactory(_factory).acceptFeeManager(); - } - function setFee(address _factory, bool _stable, uint256 _fee) public { PairFactory(_factory).setFee(_stable, _fee); } From 7470e6afcebc81b2b2bdf9cda46b7f2392a210eb Mon Sep 17 00:00:00 2001 From: Ceazor Date: Mon, 6 Mar 2023 10:56:43 -0700 Subject: [PATCH 103/156] Changes to Roles PairFactory.sol - reduced roles in PairFactory cuz deployer has perma power to setTank - made PairFactory import ownable.sol --removed team, pauser, pendingPauser, feeManger and made their functions onlyOwner Voter.sol - made governor only role that can change emergencyCouncil- not emergencyCouncil Deployment.s.sol --removed setPauser and setTeam in Deployment.s.sol for PairFactory --reversed the order of set emergencyCouncil and set governor to account for require(msg.sender == governor) -- added transferOwnership() for PairFactory instead of setTeam() --- scripts/Deployment.s.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/Deployment.s.sol b/scripts/Deployment.s.sol index 9bcd569a..030a07cd 100644 --- a/scripts/Deployment.s.sol +++ b/scripts/Deployment.s.sol @@ -96,14 +96,14 @@ contract Deployment is Script { votingEscrow.setTeam(TEAM_MULTI_SIG); minter.setTeam(TEAM_MULTI_SIG); - // Transfer pair factory ownership to multi-sig + // Transfer pairfactory ownership to MSIG (team) pairFactory.transferOwnership(TEAM_MULTI_SIG); - // Set voter's governor - voter.setGovernor(TEAM_MULTI_SIG); - // Set voter's emergency council voter.setEmergencyCouncil(TEAM_MULTI_SIG); + + // Set voter's governor + voter.setGovernor(TEAM_MULTI_SIG); // Set rewards distributor's depositor to minter contract rewardsDistributor.setDepositor(address(minter)); From 84643b2e767278e16808b5d5ad05cf1008c9474c Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 7 Mar 2023 07:27:49 +0800 Subject: [PATCH 104/156] fix: remove redundant vairables --- contracts/factories/PairFactory.sol | 1 + test/Minter.t.sol | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index 26de4a4c..eeb91df9 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -31,6 +31,7 @@ contract PairFactory is IPairFactory, Ownable { event FeeSet(address indexed setter, bool stable, uint256 fee); constructor() { + isPaused = false; stableFee = 3; // 0.03% volatileFee = 25; // 0.25% deployer = msg.sender; diff --git a/test/Minter.t.sol b/test/Minter.t.sol index 1e824dd9..bd862aba 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -102,13 +102,13 @@ contract MinterTest is BaseTest { uint256 claimable = distributor.claimable(1); /** * This has been updated from 128115516517529 to - * 4368856374421 because originally in VELO the + * 4276543748717 because originally in VELO the * constructor mints 0 tokens, but now we are minting * an initial supply instead of using the initialMint * function. */ - assertGt(claimable, 4368856374421); + assertGt(claimable, 4276543748717); distributor.claim(1); assertEq(distributor.claimable(1), 0); From 4b16d9e5047349701ca22eed53814a294b1d3e9d Mon Sep 17 00:00:00 2001 From: coolie Date: Mon, 6 Mar 2023 23:42:03 +0000 Subject: [PATCH 105/156] Revert "fix: Gauge reward token precision based on ERC20 token decimals" This reverts commit af760d027dbcc14c65d6b2bb7f7af5db9829cf83. --- contracts/Gauge.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/Gauge.sol b/contracts/Gauge.sol index 424f2461..0e77a273 100644 --- a/contracts/Gauge.sol +++ b/contracts/Gauge.sol @@ -23,6 +23,7 @@ contract Gauge is IGauge { bool public isForPair; uint internal constant DURATION = 7 days; // rewards are released over 7 days + uint internal constant PRECISION = 10 ** 18; uint internal constant MAX_REWARD_TOKENS = 16; // default snx staking contract implementation @@ -284,7 +285,7 @@ contract Gauge is IGauge { if (derivedSupply == 0) { return rewardPerTokenStored[token]; } - return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * (10**IERC20(token).decimals()) / derivedSupply); + return rewardPerTokenStored[token] + ((lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] * PRECISION / derivedSupply); } function derivedBalance(address account) public view returns (uint) { @@ -326,7 +327,7 @@ contract Gauge is IGauge { function _calcRewardPerToken(address token, uint timestamp1, uint timestamp0, uint supply, uint startTimestamp) internal view returns (uint, uint) { uint endTime = Math.max(timestamp1, startTimestamp); - return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * (10**IERC20(token).decimals()) / supply), endTime); + return (((Math.min(endTime, periodFinish[token]) - Math.min(Math.max(timestamp0, startTimestamp), periodFinish[token])) * rewardRate[token] * PRECISION / supply), endTime); } /// @dev Update stored rewardPerToken values without the last one snapshot @@ -403,13 +404,13 @@ contract Gauge is IGauge { Checkpoint memory cp1 = checkpoints[account][i+1]; (uint _rewardPerTokenStored0,) = getPriorRewardPerToken(token, cp0.timestamp); (uint _rewardPerTokenStored1,) = getPriorRewardPerToken(token, cp1.timestamp); - reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / (10**IERC20(token).decimals()); + reward += cp0.balanceOf * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / PRECISION; } } Checkpoint memory cp = checkpoints[account][_endIndex]; (uint _rewardPerTokenStored,) = getPriorRewardPerToken(token, cp.timestamp); - reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][account])) / (10**IERC20(token).decimals()); + reward += cp.balanceOf * (rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][account])) / PRECISION; return reward; } From b86bc855629fcce343d2b6b84a4a2d4e224b3765 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 7 Mar 2023 07:43:49 +0800 Subject: [PATCH 106/156] fix: remove isPaused = false in constructor --- contracts/factories/PairFactory.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/factories/PairFactory.sol b/contracts/factories/PairFactory.sol index eeb91df9..26de4a4c 100644 --- a/contracts/factories/PairFactory.sol +++ b/contracts/factories/PairFactory.sol @@ -31,7 +31,6 @@ contract PairFactory is IPairFactory, Ownable { event FeeSet(address indexed setter, bool stable, uint256 fee); constructor() { - isPaused = false; stableFee = 3; // 0.03% volatileFee = 25; // 0.25% deployer = msg.sender; From eb20b3f03d664853af37c645e20967556c49287d Mon Sep 17 00:00:00 2001 From: coolie Date: Mon, 6 Mar 2023 23:50:48 +0000 Subject: [PATCH 107/156] chore: Remove governance code --- contracts/VeloGovernor.sol | 60 -- contracts/governance/L2Governor.sol | 598 ------------------ .../governance/L2GovernorCountingSimple.sol | 109 ---- contracts/governance/L2GovernorVotes.sol | 33 - .../L2GovernorVotesQuorumFraction.sol | 87 --- readme.md | 1 - tasks/deploy/op.ts | 10 - test/NFTVote.t.sol | 80 --- test/OnChainVote.t.sol | 124 ---- test/VeloGovernor.t.sol | 196 ------ test/utils/TestGovernance.sol | 36 -- test/utils/TestL2Governance.sol | 32 - 12 files changed, 1366 deletions(-) delete mode 100644 contracts/VeloGovernor.sol delete mode 100644 contracts/governance/L2Governor.sol delete mode 100644 contracts/governance/L2GovernorCountingSimple.sol delete mode 100644 contracts/governance/L2GovernorVotes.sol delete mode 100644 contracts/governance/L2GovernorVotesQuorumFraction.sol delete mode 100644 test/NFTVote.t.sol delete mode 100644 test/OnChainVote.t.sol delete mode 100644 test/VeloGovernor.t.sol delete mode 100644 test/utils/TestGovernance.sol delete mode 100644 test/utils/TestL2Governance.sol diff --git a/contracts/VeloGovernor.sol b/contracts/VeloGovernor.sol deleted file mode 100644 index faa0804f..00000000 --- a/contracts/VeloGovernor.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -import {IGovernor} from "openzeppelin-contracts/contracts/governance/IGovernor.sol"; -import {IVotes} from "openzeppelin-contracts/contracts/governance/utils/IVotes.sol"; - -import {L2Governor} from "contracts/governance/L2Governor.sol"; -import {L2GovernorCountingSimple} from "contracts/governance/L2GovernorCountingSimple.sol"; -import {L2GovernorVotes} from "contracts/governance/L2GovernorVotes.sol"; -import {L2GovernorVotesQuorumFraction} from "contracts/governance/L2GovernorVotesQuorumFraction.sol"; - -contract VeloGovernor is - L2Governor, - L2GovernorCountingSimple, - L2GovernorVotes, - L2GovernorVotesQuorumFraction -{ - address public team; - uint256 public constant MAX_PROPOSAL_NUMERATOR = 50; // max 5% - uint256 public constant PROPOSAL_DENOMINATOR = 1000; - uint256 public proposalNumerator = 2; // start at 0.02% - - constructor(IVotes _ve) - L2Governor("Velodrome Governor") - L2GovernorVotes(_ve) - L2GovernorVotesQuorumFraction(4) // 4% - { - team = msg.sender; - } - - function votingDelay() public pure override(IGovernor) returns (uint256) { - return 15 minutes; // 1 block - } - - function votingPeriod() public pure override(IGovernor) returns (uint256) { - return 1 weeks; - } - - function setTeam(address newTeam) external { - require(msg.sender == team, "not team"); - team = newTeam; - } - - function setProposalNumerator(uint256 numerator) external { - require(msg.sender == team, "not team"); - require(numerator <= MAX_PROPOSAL_NUMERATOR, "numerator too high"); - proposalNumerator = numerator; - } - - function proposalThreshold() - public - view - override(L2Governor) - returns (uint256) - { - return - (token.getPastTotalSupply(block.timestamp) * proposalNumerator) / - PROPOSAL_DENOMINATOR; - } -} diff --git a/contracts/governance/L2Governor.sol b/contracts/governance/L2Governor.sol deleted file mode 100644 index bba2b0d8..00000000 --- a/contracts/governance/L2Governor.sol +++ /dev/null @@ -1,598 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/Governor.sol) - -pragma solidity ^0.8.0; - -import "openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol"; -import "openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol"; -import "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; -import "openzeppelin-contracts/contracts/utils/cryptography/draft-EIP712.sol"; -import "openzeppelin-contracts/contracts/utils/introspection/ERC165.sol"; -import "openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; -import "openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol"; -import "openzeppelin-contracts/contracts/utils/Address.sol"; -import "openzeppelin-contracts/contracts/utils/Context.sol"; -import "openzeppelin-contracts/contracts/utils/Timers.sol"; -import "openzeppelin-contracts/contracts/governance/IGovernor.sol"; - -/** - * @author Modified from RollCall (https://github.com/withtally/rollcall/blob/main/src/standards/L2Governor.sol) - * - * @dev Core of the governance system, designed to be extended though various modules. - * - * This contract is abstract and requires several function to be implemented in various modules: - * - * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} - * - A voting module must implement {_getVotes} - * - Additionanly, the {votingPeriod} must also be implemented - * - * _Available since v4.3._ - */ -abstract contract L2Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { - using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; - using SafeCast for uint256; - using Timers for Timers.Timestamp; - - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); - bytes32 public constant EXTENDED_BALLOT_TYPEHASH = - keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); - - struct ProposalCore { - Timers.Timestamp voteStart; - Timers.Timestamp voteEnd; - bool executed; - bool canceled; - } - - string private _name; - - mapping(uint256 => ProposalCore) private _proposals; - - // This queue keeps track of the governor operating on itself. Calls to functions protected by the - // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, - // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the - // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. - DoubleEndedQueue.Bytes32Deque private _governanceCall; - - /** - * @dev Restricts a function so it can only be executed through governance proposals. For example, governance - * parameter setters in {GovernorSettings} are protected using this modifier. - * - * The governance executing address may be different from the Governor's own address, for example it could be a - * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these - * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, - * for example, additional timelock proposers are not able to change governance parameters without going through the - * governance protocol (since v4.6). - */ - modifier onlyGovernance() { - require(_msgSender() == _executor(), "Governor: onlyGovernance"); - if (_executor() != address(this)) { - bytes32 msgDataHash = keccak256(_msgData()); - // loop until popping the expected operation - throw if deque is empty (operation not authorized) - while (_governanceCall.popFront() != msgDataHash) {} - } - _; - } - - /** - * @dev Sets the value for {name} and {version} - */ - constructor(string memory name_) EIP712(name_, version()) { - _name = name_; - } - - /** - * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) - */ - receive() external payable virtual { - require(_executor() == address(this)); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { - // In addition to the current interfaceId, also support previous version of the interfaceId that did not - // include the castVoteWithReasonAndParams() function as standard - return - interfaceId == - (type(IGovernor).interfaceId ^ - this.castVoteWithReasonAndParams.selector ^ - this.castVoteWithReasonAndParamsBySig.selector ^ - this.getVotesWithParams.selector) || - interfaceId == type(IGovernor).interfaceId || - interfaceId == type(IERC1155Receiver).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IGovernor-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IGovernor-version}. - */ - function version() public view virtual override returns (string memory) { - return "1"; - } - - /** - * @dev See {IGovernor-hashProposal}. - * - * The proposal id is produced by hashing the RLC encoded `targets` array, the `values` array, the `calldatas` array - * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id - * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in - * advance, before the proposal is submitted. - * - * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the - * same proposal (with same operation and same description) will have the same id if submitted on multiple governors - * across multiple networks. This also means that in order to execute the same operation twice (on the same - * governor) the proposer will have to change the description in order to avoid proposal id conflicts. - */ - function hashProposal( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public pure virtual override returns (uint256) { - return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); - } - - /** - * @dev See {IGovernor-state}. - */ - function state(uint256 proposalId) public view virtual override returns (ProposalState) { - ProposalCore storage proposal = _proposals[proposalId]; - - if (proposal.executed) { - return ProposalState.Executed; - } - - if (proposal.canceled) { - return ProposalState.Canceled; - } - - uint256 start = proposalSnapshot(proposalId); - - if (start == 0) { - revert("Governor: unknown proposal id"); - } - - if (start >= block.timestamp) { - return ProposalState.Pending; - } - - uint256 deadline = proposalDeadline(proposalId); - - if (deadline >= block.timestamp) { - return ProposalState.Active; - } - - if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { - return ProposalState.Succeeded; - } else { - return ProposalState.Defeated; - } - } - - /** - * @dev See {IGovernor-proposalSnapshot}. - */ - function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { - return _proposals[proposalId].voteStart.getDeadline(); - } - - /** - * @dev See {IGovernor-proposalDeadline}. - */ - function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { - return _proposals[proposalId].voteEnd.getDeadline(); - } - - /** - * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. - */ - function proposalThreshold() public view virtual returns (uint256) { - return 0; - } - - /** - * @dev Amount of votes already cast passes the threshold limit. - */ - function _quorumReached(uint256 proposalId) internal view virtual returns (bool); - - /** - * @dev Is the proposal successful or not. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); - - /** - * @dev Get the voting weight of `account` at a specific `blockTimestamp`, for a vote as described by `params`. - */ - function _getVotes( - address account, - uint256 blockTimestamp, - bytes memory params - ) internal view virtual returns (uint256); - - /** - * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. - * - * Note: Support is generic and can represent various things depending on the voting system used. - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory params - ) internal virtual; - - /** - * @dev Default additional encoded parameters used by castVote methods that don't include them - * - * Note: Should be overridden by specific implementations to use an appropriate value, the - * meaning of the additional params, in the context of that implementation - */ - function _defaultParams() internal view virtual returns (bytes memory) { - return ""; - } - - /** - * @dev See {IGovernor-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - require( - getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), - "Governor: proposer votes below proposal threshold" - ); - - uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - require(targets.length == values.length, "Governor: invalid proposal length"); - require(targets.length == calldatas.length, "Governor: invalid proposal length"); - require(targets.length > 0, "Governor: empty proposal"); - - ProposalCore storage proposal = _proposals[proposalId]; - require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); - - uint64 start = block.timestamp.toUint64() + votingDelay().toUint64(); - uint64 deadline = start + votingPeriod().toUint64(); - - proposal.voteStart.setDeadline(start); - proposal.voteEnd.setDeadline(deadline); - - emit ProposalCreated( - proposalId, - _msgSender(), - targets, - values, - new string[](targets.length), - calldatas, - start, - deadline, - description - ); - - return proposalId; - } - - /** - * @dev See {IGovernor-execute}. - */ - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public payable virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - ProposalState status = state(proposalId); - require( - status == ProposalState.Succeeded || status == ProposalState.Queued, - "Governor: proposal not successful" - ); - _proposals[proposalId].executed = true; - - emit ProposalExecuted(proposalId); - - _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); - _execute(proposalId, targets, values, calldatas, descriptionHash); - _afterExecute(proposalId, targets, values, calldatas, descriptionHash); - - return proposalId; - } - - /** - * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism - */ - function _execute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - string memory errorMessage = "Governor: call reverted without message"; - for (uint256 i = 0; i < targets.length; ++i) { - (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); - Address.verifyCallResult(success, returndata, errorMessage); - } - } - - /** - * @dev Hook before execution is triggered. - */ - function _beforeExecute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory, /* values */ - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - if (_executor() != address(this)) { - for (uint256 i = 0; i < targets.length; ++i) { - if (targets[i] == address(this)) { - _governanceCall.pushBack(keccak256(calldatas[i])); - } - } - } - } - - /** - * @dev Hook after execution is triggered. - */ - function _afterExecute( - uint256, /* proposalId */ - address[] memory, /* targets */ - uint256[] memory, /* values */ - bytes[] memory, /* calldatas */ - bytes32 /*descriptionHash*/ - ) internal virtual { - if (_executor() != address(this)) { - if (!_governanceCall.empty()) { - _governanceCall.clear(); - } - } - } - - /** - * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as - * canceled to allow distinguishing it from executed proposals. - * - * Emits a {IGovernor-ProposalCanceled} event. - */ - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - ProposalState status = state(proposalId); - - require( - status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, - "Governor: proposal not active" - ); - _proposals[proposalId].canceled = true; - - emit ProposalCanceled(proposalId); - - return proposalId; - } - - /** - * @dev See {IGovernor-getVotes}. - */ - function getVotes(address account, uint256 blockTimestamp) public view virtual override returns (uint256) { - return _getVotes(account, blockTimestamp, _defaultParams()); - } - - /** - * @dev See {IGovernor-getVotesWithParams}. - */ - function getVotesWithParams( - address account, - uint256 blockTimestamp, - bytes memory params - ) public view virtual override returns (uint256) { - return _getVotes(account, blockTimestamp, params); - } - - /** - * @dev See {IGovernor-castVote}. - */ - function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReason}. - */ - function castVoteWithReason( - uint256 proposalId, - uint8 support, - string calldata reason - ) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParams}. - */ - function castVoteWithReasonAndParams( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params - ) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev See {IGovernor-castVoteBySig}. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override returns (uint256) { - address voter = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), - v, - r, - s - ); - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override returns (uint256) { - address voter = ECDSA.recover( - _hashTypedDataV4( - keccak256( - abi.encode( - EXTENDED_BALLOT_TYPEHASH, - proposalId, - support, - keccak256(bytes(reason)), - keccak256(params) - ) - ) - ), - v, - r, - s - ); - - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve - * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). - * - * Emits a {IGovernor-VoteCast} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal virtual returns (uint256) { - return _castVote(proposalId, account, support, reason, _defaultParams()); - } - - /** - * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve - * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. - * - * Emits a {IGovernor-VoteCast} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal virtual returns (uint256) { - ProposalCore storage proposal = _proposals[proposalId]; - require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); - - uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); - _countVote(proposalId, account, support, weight, params); - - if (params.length == 0) { - emit VoteCast(account, proposalId, support, weight, reason); - } else { - emit VoteCastWithParams(account, proposalId, support, weight, reason, params); - } - - return weight; - } - - /** - * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor - * is some contract other than the governor itself, like when using a timelock, this function can be invoked - * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. - * Note that if the executor is simply the governor itself, use of `relay` is redundant. - */ - function relay( - address target, - uint256 value, - bytes calldata data - ) external virtual onlyGovernance { - Address.functionCallWithValue(target, data, value); - } - - /** - * @dev Address through which the governor executes action. Will be overloaded by module that execute actions - * through another contract such as a timelock. - */ - function _executor() internal view virtual returns (address) { - return address(this); - } - - /** - * @dev See {IERC721Receiver-onERC721Received}. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } -} diff --git a/contracts/governance/L2GovernorCountingSimple.sol b/contracts/governance/L2GovernorCountingSimple.sol deleted file mode 100644 index 0acc0881..00000000 --- a/contracts/governance/L2GovernorCountingSimple.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorCountingSimple.sol) - -pragma solidity ^0.8.0; - -import {L2Governor} from "contracts/governance/L2Governor.sol"; - -/** - * @author Modified from RollCall (https://github.com/withtally/rollcall/blob/main/src/standards/L2GovernorCountingSimple.sol) - * - * @dev Extension of {Governor} for simple, 3 options, vote counting. - * - * _Available since v4.3._ - */ -abstract contract L2GovernorCountingSimple is L2Governor { - /** - * @dev Supported vote types. Matches Governor Bravo ordering. - */ - enum VoteType { - Against, - For, - Abstain - } - - struct ProposalVote { - uint256 againstVotes; - uint256 forVotes; - uint256 abstainVotes; - mapping(address => bool) hasVoted; - } - - mapping(uint256 => ProposalVote) private _proposalVotes; - - /** - * @dev See {IGovernor-COUNTING_MODE}. - */ - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual override returns (string memory) { - return "support=bravo&quorum=for,abstain"; - } - - /** - * @dev See {IGovernor-hasVoted}. - */ - function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { - return _proposalVotes[proposalId].hasVoted[account]; - } - - /** - * @dev Accessor to the internal vote counts. - */ - function proposalVotes(uint256 proposalId) - public - view - virtual - returns ( - uint256 againstVotes, - uint256 forVotes, - uint256 abstainVotes - ) - { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - return (proposalvote.againstVotes, proposalvote.forVotes, proposalvote.abstainVotes); - } - - /** - * @dev See {Governor-_quorumReached}. - */ - function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes; - } - - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return proposalvote.forVotes > proposalvote.againstVotes; - } - - /** - * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo). - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory // params - ) internal virtual override { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - require(!proposalvote.hasVoted[account], "GovernorVotingSimple: vote already cast"); - proposalvote.hasVoted[account] = true; - - if (support == uint8(VoteType.Against)) { - proposalvote.againstVotes += weight; - } else if (support == uint8(VoteType.For)) { - proposalvote.forVotes += weight; - } else if (support == uint8(VoteType.Abstain)) { - proposalvote.abstainVotes += weight; - } else { - revert("GovernorVotingSimple: invalid value for enum VoteType"); - } - } -} diff --git a/contracts/governance/L2GovernorVotes.sol b/contracts/governance/L2GovernorVotes.sol deleted file mode 100644 index e2551ca5..00000000 --- a/contracts/governance/L2GovernorVotes.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotes.sol) - -pragma solidity ^0.8.0; - -import {IVotes} from "openzeppelin-contracts/contracts/governance/utils/IVotes.sol"; -import {L2Governor} from "contracts/governance/L2Governor.sol"; - -/** - * @author Modified from RollCall (https://github.com/withtally/rollcall/blob/main/src/standards/L2GovernorVotes.sol) - * - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token. - * - * _Available since v4.3._ - */ -abstract contract L2GovernorVotes is L2Governor { - IVotes public immutable token; - - constructor(IVotes tokenAddress) { - token = tokenAddress; - } - - /** - * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). - */ - function _getVotes( - address account, - uint256 blockTimestamp, - bytes memory /*params*/ - ) internal view virtual override returns (uint256) { - return token.getPastVotes(account, blockTimestamp); - } -} diff --git a/contracts/governance/L2GovernorVotesQuorumFraction.sol b/contracts/governance/L2GovernorVotesQuorumFraction.sol deleted file mode 100644 index e14c9b3c..00000000 --- a/contracts/governance/L2GovernorVotesQuorumFraction.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (governance/extensions/GovernorVotesQuorumFraction.sol) - -pragma solidity ^0.8.0; - -import {L2GovernorVotes} from "contracts/governance/L2GovernorVotes.sol"; - -/** - * @author Modified from RollCall (https://github.com/withtally/rollcall/blob/main/src/standards/L2GovernorVotesQuorumFraction.sol) - * - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a - * fraction of the total supply. - * - * _Available since v4.3._ - */ -abstract contract L2GovernorVotesQuorumFraction is L2GovernorVotes { - uint256 private _quorumNumerator; - - event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); - - /** - * @dev Initialize quorum as a fraction of the token's total supply. - * - * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is - * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be - * customized by overriding {quorumDenominator}. - */ - constructor(uint256 quorumNumeratorValue) { - _updateQuorumNumerator(quorumNumeratorValue); - } - - /** - * @dev Returns the current quorum numerator. See {quorumDenominator}. - */ - function quorumNumerator() public view virtual returns (uint256) { - return _quorumNumerator; - } - - /** - * @dev Returns the quorum denominator. Defaults to 100, but may be overridden. - */ - function quorumDenominator() public view virtual returns (uint256) { - return 100; - } - - /** - * @dev Returns the quorum for a block timestamp, in terms of number of votes: `supply * numerator / denominator`. - */ - function quorum(uint256 blockTimestamp) public view virtual override returns (uint256) { - return (token.getPastTotalSupply(blockTimestamp) * quorumNumerator()) / quorumDenominator(); - } - - /** - * @dev Changes the quorum numerator. - * - * Emits a {QuorumNumeratorUpdated} event. - * - * Requirements: - * - * - Must be called through a governance proposal. - * - New numerator must be smaller or equal to the denominator. - */ - function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance { - _updateQuorumNumerator(newQuorumNumerator); - } - - /** - * @dev Changes the quorum numerator. - * - * Emits a {QuorumNumeratorUpdated} event. - * - * Requirements: - * - * - New numerator must be smaller or equal to the denominator. - */ - function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { - require( - newQuorumNumerator <= quorumDenominator(), - "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator" - ); - - uint256 oldQuorumNumerator = _quorumNumerator; - _quorumNumerator = newQuorumNumerator; - - emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); - } -} diff --git a/readme.md b/readme.md index d5d50e01..843b193b 100644 --- a/readme.md +++ b/readme.md @@ -42,7 +42,6 @@ The Velodrome team engaged with Code 4rena for a security review. The results of | BribeFactory | [0xA84EA94Aa705F7d009CDDF2a60f65c0d446b748E](https://optimistic.etherscan.io/address/0xA84EA94Aa705F7d009CDDF2a60f65c0d446b748E#code) | | GaugeFactory | [0xC5be2c918EB04B091962fDF095A217A55CFA42C5](https://optimistic.etherscan.io/address/0xC5be2c918EB04B091962fDF095A217A55CFA42C5#code) | | Voter | [0x09236cfF45047DBee6B921e00704bed6D6B8Cf7e](https://optimistic.etherscan.io/address/0x09236cfF45047DBee6B921e00704bed6D6B8Cf7e#code) | -| VeloGovernor | [0x64DD805aa894dc001f8505e000c7535179D96C9E](https://optimistic.etherscan.io/address/0x64DD805aa894dc001f8505e000c7535179D96C9E#code) | | VotingEscrow | [0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26](https://optimistic.etherscan.io/address/0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26#code) | | VeArtProxy | [0x5F2f6721Ca0C5AC522BC875fA3F09bF693dcFa1D](https://optimistic.etherscan.io/address/0x5F2f6721Ca0C5AC522BC875fA3F09bF693dcFa1D#code) | | RewardsDistributor | [0x5d5Bea9f0Fc13d967511668a60a3369fD53F784F](https://optimistic.etherscan.io/address/0x5d5Bea9f0Fc13d967511668a60a3369fD53F784F#code) | diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index afff85c7..1c185ab0 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -24,7 +24,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( RewardsDistributor, Voter, Minter, - VeloGovernor, ] = await Promise.all([ ethers.getContractFactory("Velocimeter"), ethers.getContractFactory("GaugeFactory"), @@ -37,7 +36,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ethers.getContractFactory("RewardsDistributor"), ethers.getContractFactory("Voter"), ethers.getContractFactory("Minter"), - ethers.getContractFactory("VeloGovernor"), ]); const flow = await Velocimeter.deploy(); @@ -110,11 +108,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( "\n" ); - const governor = await VeloGovernor.deploy(escrow.address); - await governor.deployed(); - console.log("VeloGovernor deployed to: ", governor.address); - console.log("Args: ", escrow.address, "\n"); - // Airdrop // Initialize await flow.setMinter(minter.address); @@ -135,9 +128,6 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( await distributor.setDepositor(minter.address); console.log("Depositor set"); - await governor.setTeam(OP_CONFIG.teamMultisig) - console.log("Team set for governor"); - // Whitelist const nativeToken = [flow.address]; const tokenWhitelist = nativeToken.concat(OP_CONFIG.tokenWhitelist); diff --git a/test/NFTVote.t.sol b/test/NFTVote.t.sol deleted file mode 100644 index 91a7f81a..00000000 --- a/test/NFTVote.t.sol +++ /dev/null @@ -1,80 +0,0 @@ -pragma solidity 0.8.13; - -import "openzeppelin-contracts/contracts/access/Ownable.sol"; -import "./BaseTest.sol"; -import "utils/TestL2Governance.sol"; - -contract FlagCondition is Ownable { - bool public flag; - - function setFlag(bool _to) public onlyOwner { - flag = _to; - } -} - -contract NFTVoteTest is BaseTest { - VotingEscrow escrow; - TestL2Governance gov; - FlagCondition flag; - - function setUp() public { - deployOwners(); - deployCoins(); - deployOwners(); - - VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); - gov = new TestL2Governance(escrow); - - // test variable to vote on - flag = new FlagCondition(); - flag.transferOwnership(address(gov)); - - FLOW.mint(address(this), 1e21); - vm.roll(block.number + 1); - } - - function testLockAndPropose() public { - uint256 fourYears = 4 * 365 * 24 * 3600; - FLOW.approve(address(escrow), 1e21); - escrow.create_lock(1e21, fourYears); - uint256 quorum = gov.quorum(block.timestamp); - uint256 numVotes = gov.getVotes(address(this), block.timestamp); - uint256 thresh = gov.proposalThreshold(); // 0 for now - assertGt(numVotes, thresh); - assertGt(numVotes, quorum); // owner will win - - // vote to set the flag to true - address[] memory targets = new address[](1); - targets[0] = address(flag); - uint256[] memory values = new uint256[](1); - values[0] = 0; - bytes[] memory calldatas = new bytes[](1); - bytes memory data = abi.encodeCall(flag.setFlag, (true)); - calldatas[0] = data; - string memory description = "no description"; - - uint256 proposal_id = gov.propose(targets, values, calldatas, description); - - // start block is at 2 - vm.warp(block.timestamp + 2); - vm.roll(block.number + 1); - gov.castVote( - proposal_id, - uint8(L2GovernorCountingSimple.VoteType.For) // 1 - ); - - vm.warp(block.timestamp + 7); - vm.roll(block.number + 1); // voting period over - assertEq(uint8(gov.state(proposal_id)), 4); // 3 = defeated, 4 = succeeded - - uint256 executed_proposal_id = gov.execute( - targets, - values, - calldatas, - keccak256(bytes(description)) - ); - assertEq(executed_proposal_id, proposal_id); - assertTrue(flag.flag()); - } -} diff --git a/test/OnChainVote.t.sol b/test/OnChainVote.t.sol deleted file mode 100644 index 78fed05c..00000000 --- a/test/OnChainVote.t.sol +++ /dev/null @@ -1,124 +0,0 @@ -pragma solidity 0.8.13; - -import "solmate/test/utils/DSTestPlus.sol"; - -import "utils/TestVotingToken.sol"; -import "utils/TestGovernance.sol"; -import "utils/TestL2Governance.sol"; - -contract OnChainVoteTest is DSTestPlus { - TestVotingERC20 vt; - TestGovernance gov; - TestL2Governance gov2; - - function setUp() public { - vt = new TestVotingERC20("coin", "SYM"); - gov = new TestGovernance(vt); - gov2 = new TestL2Governance(vt); - hevm.roll(block.number + 1); - } - - function testVote() public { - assertEq(vt.owner(), address(this)); - assertEq(gov.version(), "1"); - assertEq(gov.name(), "TestGovernor"); - assertEq(gov.votingPeriod(), 7); - assertEq(gov.quorum(0), 0); - } - - function testL2Gov() public { - assertEq(gov2.version(), "1"); - assertEq(gov2.name(), "TestL2Governor"); - assertEq(gov2.votingPeriod(), 7); - assertEq(gov2.quorum(0), 0); - } - - function testProposal() public { - vt.mint(address(this), 5); - vt.mint(address(gov), 100); - - // let's vote to move 100 token here.. - address dest = address(1); - - address[] memory targets = new address[](1); - targets[0] = address(vt); - uint256[] memory values = new uint256[](1); - values[0] = 0; - bytes[] memory calldatas = new bytes[](1); - bytes memory data = abi.encodeCall(vt.transfer, (dest, 100)); - calldatas[0] = data; - string memory description = "no description"; - - uint256 proposal_id = gov.propose(targets, values, calldatas, description); - - // delegate vote power before proposal goes live - vt.delegate(address(this)); - // 1 more until active - hevm.roll(block.number + 2); - - gov.castVote( - proposal_id, - uint8(GovernorCountingSimple.VoteType.For) // 1 - ); - - assertEq(uint8(gov.state(proposal_id)), 1); // 1 = active - hevm.roll(block.number + 7); // voting period over? - assertEq(uint8(gov.state(proposal_id)), 4); // 3 = defeated, 4 = succeeded - - uint256 executed_proposal_id = gov.execute( - targets, - values, - calldatas, - keccak256(bytes(description)) - ); - assertEq(executed_proposal_id, proposal_id); - - uint256 dest_bal = vt.balanceOf(dest); - assertEq(dest_bal, 100); - } - - function testL2Proposal() public { - vt.mint(address(this), 5); - vt.mint(address(gov2), 100); - - // let's vote to move 100 token here.. - address dest = address(1); - - address[] memory targets = new address[](1); - targets[0] = address(vt); - uint256[] memory values = new uint256[](1); - values[0] = 0; - bytes[] memory calldatas = new bytes[](1); - bytes memory data = abi.encodeCall(vt.transfer, (dest, 100)); - calldatas[0] = data; - string memory description = "no description"; - - uint256 proposal_id = gov2.propose(targets, values, calldatas, description); - - // delegate vote power before proposal goes live - vt.delegate(address(this)); - // 1 more until active - hevm.warp(block.timestamp + 2); - hevm.roll(block.number + 1); - - gov2.castVote( - proposal_id, - uint8(GovernorCountingSimple.VoteType.For) // 1 - ); - - hevm.warp(block.timestamp + 7); - hevm.roll(block.number + 1); // voting period over? - assertEq(uint8(gov2.state(proposal_id)), 4); // 3 = defeated, 4 = succeeded - - uint256 executed_proposal_id = gov2.execute( - targets, - values, - calldatas, - keccak256(bytes(description)) - ); - assertEq(executed_proposal_id, proposal_id); - - uint256 dest_bal = vt.balanceOf(dest); - assertEq(dest_bal, 100); - } -} diff --git a/test/VeloGovernor.t.sol b/test/VeloGovernor.t.sol deleted file mode 100644 index 9350e541..00000000 --- a/test/VeloGovernor.t.sol +++ /dev/null @@ -1,196 +0,0 @@ -pragma solidity 0.8.13; - -import "./BaseTest.sol"; -import "contracts/VeloGovernor.sol"; - -contract VeloGovernorTest is BaseTest { - VotingEscrow escrow; - GaugeFactory gaugeFactory; - BribeFactory bribeFactory; - WrappedExternalBribeFactory wxbribeFactory; - Voter voter; - RewardsDistributor distributor; - Minter minter; - Gauge gauge; - VeloGovernor governor; - - function setUp() public { - deployOwners(); - deployCoins(); - mintStables(); - uint256[] memory amounts = new uint256[](3); - amounts[0] = 2e25; - amounts[1] = 1e25; - amounts[2] = 1e25; - mintFlow(owners, amounts); - - VeArtProxy artProxy = new VeArtProxy(); - escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); - - FLOW.approve(address(escrow), 97 * TOKEN_1); - escrow.create_lock(97 * TOKEN_1, FOUR_YEARS); - vm.roll(block.number + 1); - - // owner2 owns less than quorum, 3% - vm.startPrank(address(owner2)); - FLOW.approve(address(escrow), 3 * TOKEN_1); - escrow.create_lock(3 * TOKEN_1, FOUR_YEARS); - vm.roll(block.number + 1); - vm.stopPrank(); - - deployPairFactoryAndRouter(); - - gaugeFactory = new GaugeFactory(); - bribeFactory = new BribeFactory(); - wxbribeFactory = new WrappedExternalBribeFactory(); - voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); - - escrow.setVoter(address(voter)); - wxbribeFactory.setVoter(address(voter)); - factory.setVoter(address(voter)); - - USDC.approve(address(router), USDC_100K); - FRAX.approve(address(router), TOKEN_100K); - router.addLiquidity(address(FRAX), address(USDC), true, TOKEN_100K, USDC_100K, TOKEN_100K, USDC_100K, address(owner), block.timestamp); - - distributor = new RewardsDistributor(address(escrow)); - - minter = new Minter(address(voter), address(escrow), address(distributor)); - distributor.setDepositor(address(minter)); - FLOW.setMinter(address(minter)); - - address address1 = factory.getPair(address(FRAX), address(USDC), true); - pair = Pair(address1); - - FLOW.approve(address(gaugeFactory), 15 * TOKEN_100K); - voter.createGauge(address(pair)); - address gaugeAddress = voter.gauges(address(pair)); - gauge = Gauge(gaugeAddress); - - governor = new VeloGovernor(escrow); - voter.setGovernor(address(governor)); - } - - function testGovernorCanWhitelistTokens(address token) public { - vm.startPrank(address(governor)); - voter.whitelist(token); - vm.stopPrank(); - } - - function testFailNonGovernorCannotWhitelistTokens(address user, address token) public { - vm.assume(user != address(governor)); - - vm.startPrank(address(user)); - voter.whitelist(token); - vm.stopPrank(); - } - - function testGovernorCanCreateGaugesForAnyAddress(address a) public { - vm.assume(a != address(0)); - - vm.startPrank(address(governor)); - voter.createGauge(a); - vm.stopPrank(); - } - - function testVeVeloMergesAutoDelegates() public { - // owner2 + owner3 > quorum - vm.startPrank(address(owner3)); - FLOW.approve(address(escrow), 3 * TOKEN_1); - escrow.create_lock(3 * TOKEN_1, FOUR_YEARS); - vm.roll(block.number + 1); - uint256 pre2 = escrow.getVotes(address(owner2)); - uint256 pre3 = escrow.getVotes(address(owner3)); - - // merge - escrow.approve(address(owner2), 3); - escrow.transferFrom(address(owner3), address(owner2), 3); - vm.stopPrank(); - vm.startPrank(address(owner2)); - escrow.merge(3, 2); - vm.stopPrank(); - - // assert vote balances - uint256 post2 = escrow.getVotes(address(owner2)); - assertApproxEqAbs( - pre2 + pre3, - post2, - FOUR_YEARS // merge rounds down time lock - ); - } - - function testFailCannotProposeWithoutSufficientBalance() public { - // propose - vm.startPrank(address(owner3)); - address[] memory targets = new address[](1); - targets[0] = address(voter); - uint256[] memory values = new uint256[](1); - values[0] = 0; - bytes[] memory calldatas = new bytes[](1); - calldatas[0] = abi.encodeWithSelector(voter.whitelist.selector, address(USDC)); - string memory description = "Whitelist USDC"; - - governor.propose(targets, values, calldatas, description); - vm.stopPrank(); - } - - function testFailProposalsNeedQuorumToPass() public { - assertFalse(voter.isWhitelisted(address(USDC))); - - address[] memory targets = new address[](1); - targets[0] = address(voter); - uint256[] memory values = new uint256[](1); - values[0] = 0; - bytes[] memory calldatas = new bytes[](1); - calldatas[0] = abi.encodeWithSelector(voter.whitelist.selector, address(USDC)); - string memory description = "Whitelist USDC"; - - // propose - vm.startPrank(address(owner)); - uint256 pid = governor.propose(targets, values, calldatas, description); - vm.warp(block.timestamp + 16 minutes); // delay - vm.stopPrank(); - - // vote - vm.startPrank(address(owner2)); - governor.castVote(pid, 1); - vm.warp(block.timestamp + 1 weeks); // voting period - vm.stopPrank(); - - // execute - vm.startPrank(address(owner)); - governor.execute(targets, values, calldatas, keccak256(bytes(description))); - vm.stopPrank(); - } - - function testProposalHasQuorum() public { - assertFalse(voter.isWhitelisted(address(USDC))); - - address[] memory targets = new address[](1); - targets[0] = address(voter); - uint256[] memory values = new uint256[](1); - values[0] = 0; - bytes[] memory calldatas = new bytes[](1); - calldatas[0] = abi.encodeWithSelector(voter.whitelist.selector, address(USDC)); - string memory description = "Whitelist USDC"; - - // propose - vm.startPrank(address(owner)); - uint256 pid = governor.propose(targets, values, calldatas, description); - vm.warp(block.timestamp + 16 minutes); // delay - vm.stopPrank(); - - // vote - vm.startPrank(address(owner)); - governor.castVote(pid, 1); - vm.warp(block.timestamp + 1 weeks); // voting period - vm.stopPrank(); - - // execute - vm.startPrank(address(owner)); - governor.execute(targets, values, calldatas, keccak256(bytes(description))); - vm.stopPrank(); - - assertTrue(voter.isWhitelisted(address(USDC))); - } -} diff --git a/test/utils/TestGovernance.sol b/test/utils/TestGovernance.sol deleted file mode 100644 index cbda5ad6..00000000 --- a/test/utils/TestGovernance.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import "openzeppelin-contracts/contracts/governance/Governor.sol"; -import "openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol"; -import "openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol"; -import "openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; - -contract TestGovernance is - Governor, - GovernorVotes, - GovernorCountingSimple, - GovernorVotesQuorumFraction -{ - constructor(IVotes _token) - Governor("TestGovernor") - GovernorVotes(_token) - GovernorVotesQuorumFraction(4) - {} - - function votingDelay() public pure override returns (uint256) { - return 1; - } - - function votingPeriod() public pure override returns (uint256) { - return 7; - } - - function proposalThreshold() public pure override returns (uint256) { - return 0; - } - - function wow() public pure returns (uint256) { - return 1; - } -} diff --git a/test/utils/TestL2Governance.sol b/test/utils/TestL2Governance.sol deleted file mode 100644 index 55ca6644..00000000 --- a/test/utils/TestL2Governance.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import "contracts/governance/L2Governor.sol"; -import "contracts/governance/L2GovernorVotes.sol"; -import "contracts/governance/L2GovernorCountingSimple.sol"; -import "contracts/governance/L2GovernorVotesQuorumFraction.sol"; - -contract TestL2Governance is - L2Governor, - L2GovernorVotes, - L2GovernorCountingSimple, - L2GovernorVotesQuorumFraction -{ - constructor(IVotes _token) - L2Governor("TestL2Governor") - L2GovernorVotes(_token) - L2GovernorVotesQuorumFraction(4) - {} - - function votingDelay() public pure override returns (uint256) { - return 1; - } - - function votingPeriod() public pure override returns (uint256) { - return 7; - } - - function proposalThreshold() public pure override returns (uint256) { - return 0; - } -} From 140004db9a1394d19f7f54b139e055f46f226329 Mon Sep 17 00:00:00 2001 From: Ceazor Date: Mon, 6 Mar 2023 19:13:01 -0700 Subject: [PATCH 108/156] pair fetch tank from PairFactory so all pairs depend on PF tank() --- contracts/Pair.sol | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 4f8fe734..fed4a661 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -36,7 +36,6 @@ contract Pair is IPair { address immutable factory; address public externalBribe; address public voter; - address public immutable tank; bool public hasGauge; // Structure to capture time period obervations every 30 minutes, used for local oracles @@ -116,6 +115,10 @@ contract Pair is IPair { require(success && (data.length == 0 || abi.decode(data, (bool)))); } + function tank() public view returns (address) { + return PairFactory(factory).tank(); + } + function setExternalBribe(address _externalBribe) external { require(externalBribe == address(0), 'External bribe has already been set.'); require(msg.sender == voter, 'Only voter can set external bribe'); @@ -153,8 +156,9 @@ contract Pair is IPair { IBribe(externalBribe).notifyRewardAmount(token, amount); // transfer fees to exBribes emit GaugeFees(token, amount, externalBribe); } else { - _safeTransfer(token, tank, amount); // transfer the fees to tank MSig for gaugeless LPs - emit TankFees(token, amount, tank); + _tank = tank(); + _safeTransfer(token, _tank, amount); // transfer the fees to tank MSig for gaugeless LPs + emit TankFees(token, amount, _tank); } } } From 6fdefeb33c5b9e57a9a6d79cfcfaa74f5afae666 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 7 Mar 2023 10:27:34 +0800 Subject: [PATCH 109/156] fix: fix pair tanks --- contracts/Pair.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index fed4a661..c062aae6 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -83,7 +83,6 @@ contract Pair is IPair { constructor() { factory = msg.sender; voter = PairFactory(msg.sender).voter(); - tank = PairFactory(msg.sender).tank(); (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); if (_stable) { @@ -156,7 +155,7 @@ contract Pair is IPair { IBribe(externalBribe).notifyRewardAmount(token, amount); // transfer fees to exBribes emit GaugeFees(token, amount, externalBribe); } else { - _tank = tank(); + address _tank = tank(); _safeTransfer(token, _tank, amount); // transfer the fees to tank MSig for gaugeless LPs emit TankFees(token, amount, _tank); } From 7442dbfb0064add2f881623ddb753f3e013e7df2 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 7 Mar 2023 18:46:10 +0800 Subject: [PATCH 110/156] fix: change safeTransferFrom to safeTransfer for v2 tokens in redeem function --- contracts/FlowConvertor.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/FlowConvertor.sol b/contracts/FlowConvertor.sol index 116e5460..64662cdb 100644 --- a/contracts/FlowConvertor.sol +++ b/contracts/FlowConvertor.sol @@ -29,9 +29,8 @@ contract FlowConvertor is Ownable { address(this), amount ); - SafeERC20.safeTransferFrom( + SafeERC20.safeTransfer( IERC20(v2), - address(this), _msgSender(), amount ); From d1b5464744e01e80492b171462cbeeee305ae62d Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Wed, 8 Mar 2023 12:24:11 +0800 Subject: [PATCH 111/156] fix: use IPairFactory in Pair.sol --- contracts/Pair.sol | 17 ++++++++--------- contracts/interfaces/IPairFactory.sol | 5 +++++ test/utils/TestOwner.sol | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index c062aae6..67b1fe31 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -5,8 +5,7 @@ import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; import 'contracts/interfaces/IERC20.sol'; import 'contracts/interfaces/IPair.sol'; import 'contracts/interfaces/IPairCallee.sol'; -import 'contracts/factories/PairFactory.sol'; - +import 'contracts/interfaces/IPairFactory.sol'; import 'contracts/interfaces/IBribe.sol'; // The base pair of pools, either stable or volatile @@ -82,8 +81,8 @@ contract Pair is IPair { constructor() { factory = msg.sender; - voter = PairFactory(msg.sender).voter(); - (address _token0, address _token1, bool _stable) = PairFactory(msg.sender).getInitializable(); + voter = IPairFactory(msg.sender).voter(); + (address _token0, address _token1, bool _stable) = IPairFactory(msg.sender).getInitializable(); (token0, token1, stable) = (_token0, _token1, _stable); if (_stable) { name = string(abi.encodePacked("StableV1 AMM - ", IERC20(_token0).symbol(), "/", IERC20(_token1).symbol())); @@ -115,7 +114,7 @@ contract Pair is IPair { } function tank() public view returns (address) { - return PairFactory(factory).tank(); + return IPairFactory(factory).tank(); } function setExternalBribe(address _externalBribe) external { @@ -303,7 +302,7 @@ contract Pair is IPair { // this low-level function should be called from a contract which performs important safety checks function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { - require(!PairFactory(factory).isPaused()); + require(!IPairFactory(factory).isPaused()); require(amount0Out > 0 || amount1Out > 0, 'IOA'); // Pair: INSUFFICIENT_OUTPUT_AMOUNT (uint _reserve0, uint _reserve1) = (reserve0, reserve1); require(amount0Out < _reserve0 && amount1Out < _reserve1, 'IL'); // Pair: INSUFFICIENT_LIQUIDITY @@ -324,8 +323,8 @@ contract Pair is IPair { require(amount0In > 0 || amount1In > 0, 'IIA'); // Pair: INSUFFICIENT_INPUT_AMOUNT { // scope for reserve{0,1}Adjusted, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); - if (amount0In > 0) _sendTokenFees(token0, amount0In * PairFactory(factory).getFee(stable) / 10000); - if (amount1In > 0) _sendTokenFees(token1, amount1In * PairFactory(factory).getFee(stable) / 10000); + if (amount0In > 0) _sendTokenFees(token0, amount0In * IPairFactory(factory).getFee(stable) / 10000); + if (amount1In > 0) _sendTokenFees(token1, amount1In * IPairFactory(factory).getFee(stable) / 10000); _balance0 = IERC20(_token0).balanceOf(address(this)); // since we removed tokens, we need to reconfirm balances, can also simply use previous balance - amountIn/ 10000, but doing balanceOf again as safety check _balance1 = IERC20(_token1).balanceOf(address(this)); // The curve, either x3y+y3x for stable pools, or x*y for volatile pools @@ -382,7 +381,7 @@ contract Pair is IPair { function getAmountOut(uint amountIn, address tokenIn) external view returns (uint) { (uint _reserve0, uint _reserve1) = (reserve0, reserve1); - amountIn -= amountIn * PairFactory(factory).getFee(stable) / 10000; // remove fee from amount received + amountIn -= amountIn * IPairFactory(factory).getFee(stable) / 10000; // remove fee from amount received return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); } diff --git a/contracts/interfaces/IPairFactory.sol b/contracts/interfaces/IPairFactory.sol index f943725a..7e732fce 100644 --- a/contracts/interfaces/IPairFactory.sol +++ b/contracts/interfaces/IPairFactory.sol @@ -3,7 +3,12 @@ pragma solidity 0.8.13; interface IPairFactory { function allPairsLength() external view returns (uint); function isPair(address pair) external view returns (bool); + function isPaused() external view returns (bool); function pairCodeHash() external pure returns (bytes32); + function getFee(bool _stable) external view returns (uint256); function getPair(address tokenA, address token, bool stable) external view returns (address); + function getInitializable() external view returns (address, address, bool); function createPair(address tokenA, address tokenB, bool stable) external returns (address pair); + function voter() external view returns (address); + function tank() external view returns (address); } diff --git a/test/utils/TestOwner.sol b/test/utils/TestOwner.sol index 5f55f85c..50296da7 100644 --- a/test/utils/TestOwner.sol +++ b/test/utils/TestOwner.sol @@ -4,6 +4,7 @@ import "solmate/test/utils/mocks/MockERC20.sol"; import "contracts/Gauge.sol"; import "contracts/Minter.sol"; import "contracts/Pair.sol"; +import "contracts/factories/PairFactory.sol"; import "contracts/Router.sol"; import "contracts/Flow.sol"; import "contracts/VotingEscrow.sol"; From d60165e6b8e0d82a85c5d6b7d58fffbbecb212be Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 9 Mar 2023 08:20:43 +0800 Subject: [PATCH 112/156] fix: remove experimental features in router --- contracts/Router.sol | 125 ------------------------------------------- 1 file changed, 125 deletions(-) diff --git a/contracts/Router.sol b/contracts/Router.sol index a5b5fed2..59d5d3b1 100644 --- a/contracts/Router.sol +++ b/contracts/Router.sol @@ -430,129 +430,4 @@ contract Router is IRouter { token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool)))); } - - // Experimental Extension [eth.guru/solidly/Router02] - - // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens)**** - function removeLiquidityETHSupportingFeeOnTransferTokens( - address token, - bool stable, - uint liquidity, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline - ) public ensure(deadline) returns (uint amountToken, uint amountETH) { - (amountToken, amountETH) = removeLiquidity( - token, - address(weth), - stable, - liquidity, - amountTokenMin, - amountETHMin, - address(this), - deadline - ); - _safeTransfer(token, to, IERC20(token).balanceOf(address(this))); - weth.withdraw(amountETH); - _safeTransferETH(to, amountETH); - } - function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( - address token, - bool stable, - uint liquidity, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline, - bool approveMax, uint8 v, bytes32 r, bytes32 s - ) external returns (uint amountToken, uint amountETH) { - address pair = pairFor(token, address(weth), stable); - uint value = approveMax ? type(uint).max : liquidity; - IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); - (amountToken, amountETH) = removeLiquidityETHSupportingFeeOnTransferTokens( - token, stable, liquidity, amountTokenMin, amountETHMin, to, deadline - ); - } - // **** SWAP (supporting fee-on-transfer tokens) **** - // requires the initial amount to have already been sent to the first pair - function _swapSupportingFeeOnTransferTokens(route[] memory routes, address _to) internal virtual { - for (uint i; i < routes.length; i++) { - (address input, address output,) = (routes[i].from, routes[i].to, routes[i].stable); - (address token0,) = sortTokens(input, output); - IPair pair = IPair(pairFor(routes[i].from, routes[i].to, routes[i].stable)); - uint amountInput; - uint amountOutput; - { // scope to avoid stack too deep errors - (uint reserve0, uint reserve1,) = pair.getReserves(); - (uint reserveInput,) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); - amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput; - amountOutput = pair.getAmountOut(amountInput, input); - } - (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); - address to = i < routes.length - 1 ? pairFor(routes[i+1].from, routes[i+1].to, routes[i+1].stable) : _to; - pair.swap(amount0Out, amount1Out, to, new bytes(0)); - } - } - function swapExactTokensForTokensSupportingFeeOnTransferTokens( - uint amountIn, - uint amountOutMin, - route[] calldata routes, - address to, - uint deadline - ) external ensure(deadline) { - _safeTransferFrom( - routes[0].from, - msg.sender, - pairFor(routes[0].from, routes[0].to, routes[0].stable), - amountIn - ); - uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to); - _swapSupportingFeeOnTransferTokens(routes, to); - require( - IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >= amountOutMin, - 'Router: INSUFFICIENT_OUTPUT_AMOUNT' - ); - } - function swapExactETHForTokensSupportingFeeOnTransferTokens( - uint amountOutMin, - route[] calldata routes, - address to, - uint deadline - ) - external - payable - ensure(deadline) - { - require(routes[0].from == address(weth), 'Router: INVALID_PATH'); - uint amountIn = msg.value; - weth.deposit{value: amountIn}(); - assert(weth.transfer(pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn)); - uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to); - _swapSupportingFeeOnTransferTokens(routes, to); - require( - IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >= amountOutMin, - 'Router: INSUFFICIENT_OUTPUT_AMOUNT' - ); - } - function swapExactTokensForETHSupportingFeeOnTransferTokens( - uint amountIn, - uint amountOutMin, - route[] calldata routes, - address to, - uint deadline - ) - external - ensure(deadline) - { - require(routes[routes.length - 1].to == address(weth), 'Router: INVALID_PATH'); - _safeTransferFrom( - routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn - ); - _swapSupportingFeeOnTransferTokens(routes, address(this)); - uint amountOut = IERC20(address(weth)).balanceOf(address(this)); - require(amountOut >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT'); - weth.withdraw(amountOut); - _safeTransferETH(to, amountOut); - } } From 28db1cb86aa295b0a64a09e08eae89dbc74a30c0 Mon Sep 17 00:00:00 2001 From: coolie Date: Thu, 9 Mar 2023 00:46:31 +0000 Subject: [PATCH 113/156] fix: Handle tax tokens in notifyRewardAmount --- contracts/ExternalBribe.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/ExternalBribe.sol b/contracts/ExternalBribe.sol index 41ce2031..a3fa7938 100644 --- a/contracts/ExternalBribe.sol +++ b/contracts/ExternalBribe.sol @@ -290,7 +290,12 @@ contract ExternalBribe is IBribe { uint adjustedTstamp = getEpochStart(block.timestamp); uint epochRewards = tokenRewardsPerEpoch[token][adjustedTstamp]; + uint256 balanceBefore = IERC20(token).balanceOf(address(this)); _safeTransferFrom(token, msg.sender, address(this), amount); + uint256 balanceAfter = IERC20(token).balanceOf(address(this)); + + amount = balanceAfter - balanceBefore; + tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount; periodFinish[token] = adjustedTstamp + DURATION; From a7faea64c6902b4f7df90ca883a5a9508b03baad Mon Sep 17 00:00:00 2001 From: coolie Date: Thu, 9 Mar 2023 00:57:33 +0000 Subject: [PATCH 114/156] fix: Handle tax tokens in Gauge.notifyRewardAmount --- contracts/Gauge.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contracts/Gauge.sol b/contracts/Gauge.sol index 0e77a273..8001569e 100644 --- a/contracts/Gauge.sol +++ b/contracts/Gauge.sol @@ -508,13 +508,19 @@ contract Gauge is IGauge { (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, type(uint).max, true); if (block.timestamp >= periodFinish[token]) { + uint256 balanceBefore = IERC20(token).balanceOf(address(this)); _safeTransferFrom(token, msg.sender, address(this), amount); + uint256 balanceAfter = IERC20(token).balanceOf(address(this)); + amount = balanceAfter - balanceBefore; rewardRate[token] = amount / DURATION; } else { uint _remaining = periodFinish[token] - block.timestamp; uint _left = _remaining * rewardRate[token]; require(amount > _left); + uint256 balanceBefore = IERC20(token).balanceOf(address(this)); _safeTransferFrom(token, msg.sender, address(this), amount); + uint256 balanceAfter = IERC20(token).balanceOf(address(this)); + amount = balanceAfter - balanceBefore; rewardRate[token] = (amount + _left) / DURATION; } require(rewardRate[token] > 0); From dc8da3e67aa682b5dbb9302101d90bbdc10c148f Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 9 Mar 2023 12:28:37 +0800 Subject: [PATCH 115/156] fix: reduce MAX_REWARD_TOKENS from 16 to 4 in Gauge --- contracts/Gauge.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/Gauge.sol b/contracts/Gauge.sol index 8001569e..f901eba1 100644 --- a/contracts/Gauge.sol +++ b/contracts/Gauge.sol @@ -24,7 +24,7 @@ contract Gauge is IGauge { uint internal constant DURATION = 7 days; // rewards are released over 7 days uint internal constant PRECISION = 10 ** 18; - uint internal constant MAX_REWARD_TOKENS = 16; + uint internal constant MAX_REWARD_TOKENS = 4; // default snx staking contract implementation mapping(address => uint) public rewardRate; From 52be63b8b2da4f8802d4b9259d87c8205996facf Mon Sep 17 00:00:00 2001 From: Ceazor <73511897+Ceazor@users.noreply.github.com> Date: Wed, 8 Mar 2023 23:25:56 -0700 Subject: [PATCH 116/156] add TaxTkn notifyReward Logic to wExternalBribe --- contracts/WrappedExternalBribe.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/WrappedExternalBribe.sol b/contracts/WrappedExternalBribe.sol index d44d4ea5..ecbc1a8f 100644 --- a/contracts/WrappedExternalBribe.sol +++ b/contracts/WrappedExternalBribe.sol @@ -161,7 +161,12 @@ contract WrappedExternalBribe { uint adjustedTstamp = getEpochStart(block.timestamp); uint epochRewards = tokenRewardsPerEpoch[token][adjustedTstamp]; + uint256 balanceBefore = IERC20(token).balanceOf(address(this)); _safeTransferFrom(token, msg.sender, address(this), amount); + uint256 balanceAfter = IERC20(token).balanceOf(address(this)); + + amount = balanceAfter - balanceBefore; + tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount; periodFinish[token] = adjustedTstamp + DURATION; From 79212b38883d67c009d20e8a417ddab11bc7ae0d Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 10 Mar 2023 18:09:08 +0800 Subject: [PATCH 117/156] fix: remove unused constant in Minter.sol --- contracts/Minter.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/Minter.sol b/contracts/Minter.sol index 88bd1cb5..a1a38638 100644 --- a/contracts/Minter.sol +++ b/contracts/Minter.sol @@ -22,7 +22,6 @@ contract Minter is IMinter { IRewardsDistributor public immutable _rewards_distributor; uint public weekly = 13_000_000 * 1e18; // represents a starting weekly emission of 13M FLOW (FLOW has 18 decimals) uint public active_period; - uint internal constant LOCK = 86400 * 7 * 52 * 4; address internal initializer; address public team; From c4828cb30a5ea5c0ef98905df90527626188a4f4 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 11 Mar 2023 12:10:49 +0800 Subject: [PATCH 118/156] refactor: rename FOUR_YEARS in test cases --- test/Minter.t.sol | 2 +- test/MinterTeamEmissions.t.sol | 2 +- test/Pair.t.sol | 2 +- test/VeloVoting.t.sol | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Minter.t.sol b/test/Minter.t.sol index bd862aba..7076e998 100644 --- a/test/Minter.t.sol +++ b/test/Minter.t.sol @@ -73,7 +73,7 @@ contract MinterTest is BaseTest { claims[0] = Minter.Claim({ claimant: address(owner), amount: TOKEN_1M, - lockTime: 86400 * 7 * 52 * 4 + lockTime: FOUR_YEARS }); minter.initialMintAndLock(claims, 2e25); minter.startActivePeriod(); diff --git a/test/MinterTeamEmissions.t.sol b/test/MinterTeamEmissions.t.sol index a7ea4b6b..b9f9adcb 100644 --- a/test/MinterTeamEmissions.t.sol +++ b/test/MinterTeamEmissions.t.sol @@ -89,7 +89,7 @@ contract MinterTeamEmissions is BaseTest { claims[0] = Minter.Claim({ claimant: address(owner), amount: TOKEN_1M, - lockTime: 86400 * 7 * 52 * 4 + lockTime: FOUR_YEARS }); minter.initialMintAndLock(claims, 13 * TOKEN_1M); minter.startActivePeriod(); diff --git a/test/Pair.t.sol b/test/Pair.t.sol index fc2088d8..9519717a 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -596,7 +596,7 @@ contract PairTest is BaseTest { claims[0] = Minter.Claim({ claimant: address(owner), amount: TOKEN_1, - lockTime: 86400 * 7 * 52 * 4 + lockTime: FOUR_YEARS }); minter.initialMintAndLock(claims, TOKEN_1); minter.startActivePeriod(); diff --git a/test/VeloVoting.t.sol b/test/VeloVoting.t.sol index 4c9fe537..f809a014 100644 --- a/test/VeloVoting.t.sol +++ b/test/VeloVoting.t.sol @@ -91,7 +91,7 @@ contract VeloVotingTest is BaseTest { claims[0] = Minter.Claim({ claimant: address(owner), amount: TOKEN_1M, - lockTime: 86400 * 7 * 52 * 4 + lockTime: FOUR_YEARS }); minter.initialMintAndLock(claims, 13 * TOKEN_1M); minter.startActivePeriod(); From 154032c53683744d5fa1783c7e08543579f20236 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 11 Mar 2023 12:24:32 +0800 Subject: [PATCH 119/156] refactor: rename variable amount0 to amount in events of Pair.sol --- contracts/Pair.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Pair.sol b/contracts/Pair.sol index 67b1fe31..ca8db433 100644 --- a/contracts/Pair.sol +++ b/contracts/Pair.sol @@ -59,8 +59,8 @@ contract Pair is IPair { uint public reserve0CumulativeLast; uint public reserve1CumulativeLast; - event TankFees(address indexed token, uint amount0, address tank); - event GaugeFees(address indexed token, uint amount0, address externalBribe); + event TankFees(address indexed token, uint amount, address tank); + event GaugeFees(address indexed token, uint amount, address externalBribe); event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( From 57b7c3f7ef6b5fc6e34ef7463322b6a26d323a05 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Wed, 8 Mar 2023 01:37:51 +0800 Subject: [PATCH 120/156] fix: remove setting owner at constructor of FlowVestor --- contracts/FlowVestor.sol | 4 +--- scripts/TeamMemberVesting.s.sol | 10 +++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/contracts/FlowVestor.sol b/contracts/FlowVestor.sol index 8c835ba2..9b2a16ff 100644 --- a/contracts/FlowVestor.sol +++ b/contracts/FlowVestor.sol @@ -63,10 +63,8 @@ contract FlowVestor is Ownable { * Additionally, it transfers ownership to the Owner contract that needs to consequently * initiate the vesting period via {begin} after it mints the necessary amount to the contract. */ - constructor(address _admin, address _FLOW) { - require(_admin != _ZERO_ADDRESS, "Misconfiguration"); + constructor(address _FLOW) { FLOW = IERC20(_FLOW); - transferOwnership(_admin); } /* ========== VIEWS ========== */ diff --git a/scripts/TeamMemberVesting.s.sol b/scripts/TeamMemberVesting.s.sol index c0f53855..ccbc795d 100644 --- a/scripts/TeamMemberVesting.s.sol +++ b/scripts/TeamMemberVesting.s.sol @@ -11,20 +11,20 @@ contract TeamMemberVesting is Script { address private constant TEAM_MULTI_SIG = 0x13eeB8EdfF60BbCcB24Ec7Dd5668aa246525Dc51; // team member addresses - address private constant T0RB1K = 0x0b776552c1aef1dc33005dd25acda22493b6615d; - address private constant MOTTO = 0x78e801136f77805239a7f533521a7a5570f572c8; - address private constant COOLIE = 0x03b88dacb7c21b54cefecc297d981e5b721a9df1; + address private constant T0RB1K = 0x0b776552c1Aef1Dc33005DD25AcDA22493b6615d; + address private constant MOTTO = 0x78e801136F77805239A7F533521A7a5570F572C8; + address private constant COOLIE = 0x03B88DacB7c21B54cEfEcC297D981E5b721A9dF1; address private constant ADMIN = 0xBC3043983276887f6b6F164Df33646479C9b1653; // TODO: Fill the address - address private constant FLOW = 0x0000000000000000000000000000000000000000; + address private constant FLOW = 0x78e489523291581205Ea3fA16a69689EcA79757A; function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); vm.startBroadcast(deployerPrivateKey); - FlowVestor flowVestor = new FlowVestor(ADMIN, FLOW); + FlowVestor flowVestor = new FlowVestor(FLOW); IERC20(FLOW).approve(address(flowVestor), 4_500_000e18); flowVestor.vestFor(T0RB1K, 2_000_000e18); From 5966778c2264d5ab062260216508b27468070c8b Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 11 Mar 2023 12:14:30 +0800 Subject: [PATCH 121/156] refactor: remove optimismConfig.ts --- tasks/deploy/constants/optimismConfig.ts | 97 ------------------------ tasks/deploy/op.ts | 3 +- 2 files changed, 1 insertion(+), 99 deletions(-) delete mode 100644 tasks/deploy/constants/optimismConfig.ts diff --git a/tasks/deploy/constants/optimismConfig.ts b/tasks/deploy/constants/optimismConfig.ts deleted file mode 100644 index f25a4c4d..00000000 --- a/tasks/deploy/constants/optimismConfig.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { ethers } from "ethers"; - -const TOKEN_DECIMALS = ethers.BigNumber.from("10").pow( - ethers.BigNumber.from("18") -); -const MILLION = ethers.BigNumber.from("10").pow(ethers.BigNumber.from("6")); - -const FOUR_MILLION = ethers.BigNumber.from("4") - .mul(MILLION) - .mul(TOKEN_DECIMALS); -const TEN_MILLION = ethers.BigNumber.from("10") - .mul(MILLION) - .mul(TOKEN_DECIMALS); -const TWENTY_MILLION = ethers.BigNumber.from("20") - .mul(MILLION) - .mul(TOKEN_DECIMALS); -const PARTNER_MAX = ethers.BigNumber.from("78") - .mul(MILLION) - .mul(TOKEN_DECIMALS); - -const TEAM_MULTISIG = "0xb074ec6c37659525EEf2Fb44478077901F878012"; -const TEAM_EOA = "0xe247340f06FCB7eb904F16a48C548221375b5b96"; - -const optimismConfig = { - // Chain const - lzChainId: 11, - lzEndpoint: "0x3c2269811836af69497E5F486A85D7316753cf62", - - // Tokens - WETH: "0x4200000000000000000000000000000000000006", - USDC: "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", - - // Addresses - teamEOA: TEAM_EOA, - teamMultisig: TEAM_MULTISIG, - emergencyCouncil: "0xcC2D01030eC2cd187346F70bFc483F24488C32E8", - - merkleRoot: - "0xbb99a09fb3b8499385659e82a8da93596dd07082fe86981ec06c83181dee489f", - tokenWhitelist: [ - "0x4200000000000000000000000000000000000042", // OP - "0x4200000000000000000000000000000000000006", // WETH - "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", // USDC - "0x2E3D870790dC77A83DD1d18184Acc7439A53f475", // FRAX - "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", // DAI - "0x8c6f28f2F1A3C87F0f938b96d27520d9751ec8d9", // sUSD - "0x217D47011b23BB961eB6D93cA9945B7501a5BB11", // THALES - "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", // LYRA - "0x67CCEA5bb16181E7b4109c9c2143c24a1c2205Be", // FXS - "0x9e1028F5F1D5eDE59748FFceE5532509976840E0", // PERP - "0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4", // SNX - "0xCB8FA9a76b8e203D8C3797bF438d8FB81Ea3326A", // alUSD - "0x3E29D3A9316dAB217754d13b28646B76607c5f04", // alETH - "0x8aE125E8653821E851F12A49F7765db9a9ce7384", // DOLA - "0x10010078a54396F62c96dF8532dc2B4847d47ED3", // HND - // "", // BTRFLY -- N/A - // "", // pxFLOW -- N/A - "0xc40F949F8a4e094D1b49a23ea9241D289B7b2819", // LUSD - // "", // wstETH -- N/A - // "", // HOP -- N/A - ], - partnerAddrs: [ - TEAM_EOA, // FLOW - "0x4a84675512949f81EBFEAAcC6C00D03eDd329de5", // OP - TEAM_EOA, // SNX -- custodied - "0xa283139017a2f5BAdE8d8e25412C600055D318F8", // INV - "0xDcf664d0f76E99eaA2DBD569474d0E75dC899FCD", // PERP - "0x489863b61C625a15C74FB4C21486baCb4A3937AB", // THALES - "0x641f26c67A5D0829Ae61019131093B6a7c7d18a3", // HND - "0xC224bf25Dcc99236F00843c7D8C4194abE8AA94a", // ALCX - "0xB6DACAE4eF97b4817d54df8e005269f509f803f9", // LYRA - TEAM_EOA, // MKR -- custodied - TEAM_EOA, // HOP -- custodied - "0x0dF840dCbf1229262A4125C1fc559bd338eC9491", // FRAX - "0x2E33A660742e813aD948fB9f7d682FE461E5fbf3", // BTRFLY - "0xd2D4e9024D8C90aB52032a9F1e0d92D4cE20191B", // LUSD - ], - partnerAmts: [ - TEN_MILLION, - TWENTY_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - FOUR_MILLION, - ], - partnerMax: PARTNER_MAX, -}; - -export default optimismConfig; diff --git a/tasks/deploy/op.ts b/tasks/deploy/op.ts index 1c185ab0..773e4d17 100644 --- a/tasks/deploy/op.ts +++ b/tasks/deploy/op.ts @@ -1,6 +1,5 @@ import { task } from "hardhat/config"; -import optimismConfig from "./constants/optimismConfig"; import testOptimismConfig from "./constants/testOptimismConfig"; task("deploy:op", "Deploys Optimism contracts").setAction(async function ( @@ -9,7 +8,7 @@ task("deploy:op", "Deploys Optimism contracts").setAction(async function ( ) { const mainnet = false; - const OP_CONFIG = mainnet ? optimismConfig : testOptimismConfig; + const OP_CONFIG = testOptimismConfig; // Load const [ From 8af1743ead88447d8a86f7d65f9877a266fcd95d Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 17 Mar 2023 17:34:29 +0800 Subject: [PATCH 122/156] fix: fix testGaugeClaimRewards3 --- test/Pair.t.sol | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 9519717a..539d5ba4 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -16,6 +16,7 @@ contract PairTest is BaseTest { Gauge gauge2; Gauge gauge3; ExternalBribe xbribe; + WrappedExternalBribe wxbribe; function deployPairCoins() public { vm.warp(block.timestamp + 1 weeks); // put some initial time in @@ -121,7 +122,7 @@ contract PairTest is BaseTest { function confirmTokensForFraxUsdc() public { confirmFraxDeployment(); deployPairFactoryAndRouter(); - routerAddLiquidity(); + deployVoter(); deployPairWithOwner(address(owner)); deployPairWithOwner(address(owner2)); @@ -295,6 +296,7 @@ contract PairTest is BaseTest { gauge3 = Gauge(gaugeAddress3); xbribe = ExternalBribe(xBribeAddress); + wxbribe = WrappedExternalBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); pair.approve(address(gauge), PAIR_1); pair.approve(address(staking), PAIR_1); @@ -355,11 +357,11 @@ contract PairTest is BaseTest { withdrawGaugeStake(); FLOW.approve(address(gauge), PAIR_1); - FLOW.approve(address(xbribe), PAIR_1); + FLOW.approve(address(wxbribe), PAIR_1); FLOW.approve(address(staking), PAIR_1); gauge.notifyRewardAmount(address(FLOW), PAIR_1); - xbribe.notifyRewardAmount(address(FLOW), PAIR_1); + wxbribe.notifyRewardAmount(address(FLOW), PAIR_1); staking.notifyRewardAmount(PAIR_1); assertEq(gauge.rewardRate(address(FLOW)), 1653); @@ -506,10 +508,10 @@ contract PairTest is BaseTest { address[] memory rewards = new address[](1); rewards[0] = address(FLOW); - xbribe.getReward(1, rewards); + wxbribe.getReward(1, rewards); vm.warp(block.timestamp + 691200); vm.roll(block.number + 1); - xbribe.getReward(1, rewards); + wxbribe.getReward(1, rewards); } function routerPair1GetAmountsOutAndSwapExactTokensForTokens2() public { @@ -580,10 +582,11 @@ contract PairTest is BaseTest { address[] memory rewards = new address[](2); rewards[0] = address(FRAX); rewards[1] = address(USDC); - xbribe.getReward(1, rewards); + wxbribe.getReward(1, rewards); address[] memory gauges = new address[](1); gauges[0] = address(gauge); + voter.distribute(gauges[0]); } function minterMint() public { From 381ad83c0713ee4dfca12713280ac733bfa24711 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sat, 18 Mar 2023 22:36:26 +0800 Subject: [PATCH 123/156] fix: fix number of elements in the array --- test/Pair.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 539d5ba4..81c15ff5 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -474,9 +474,9 @@ contract PairTest is BaseTest { function voteHackingBreakMint() public { gaugePokeHacking2(); - address[] memory pools = new address[](2); + address[] memory pools = new address[](1); pools[0] = address(pair); - uint256[] memory weights = new uint256[](2); + uint256[] memory weights = new uint256[](1); weights[0] = 5000; vm.warp(block.timestamp + 1 weeks); From 811b35700221fb236387d4c8c4a1a0b15e0adce4 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Mon, 20 Mar 2023 17:25:21 +0800 Subject: [PATCH 124/156] fix: fix testGaugeClaimRewards3 --- test/Pair.t.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 81c15ff5..1d21061d 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -422,6 +422,7 @@ contract PairTest is BaseTest { assertEq(xbribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); vm.warp(block.timestamp + 1 weeks); + voter.vote(4, pools, weights); voter.reset(1); assertLt(voter.usedWeights(1), escrow.balanceOfNFT(1)); assertEq(voter.usedWeights(1), 0); From f7c58c4f693fe54f687ea4e5c7f3f06576e78ded Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Mon, 20 Mar 2023 17:45:59 +0800 Subject: [PATCH 125/156] chore: add comment in pair.t.sol --- test/Pair.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 1d21061d..0e0657de 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -422,7 +422,7 @@ contract PairTest is BaseTest { assertEq(xbribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); vm.warp(block.timestamp + 1 weeks); - voter.vote(4, pools, weights); + voter.vote(4, pools, weights); // TODO: remove this temp fix for zero votes in pools voter.reset(1); assertLt(voter.usedWeights(1), escrow.balanceOfNFT(1)); assertEq(voter.usedWeights(1), 0); From 5eaf7c57e99de25e915ba08ed5ce498301e98f7c Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 23 Mar 2023 16:38:58 +0800 Subject: [PATCH 126/156] fix: fix reset bug leading to division by 0 --- contracts/WrappedExternalBribe.sol | 11 +++++++++-- test/Pair.t.sol | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/contracts/WrappedExternalBribe.sol b/contracts/WrappedExternalBribe.sol index ecbc1a8f..c86d22e9 100644 --- a/contracts/WrappedExternalBribe.sol +++ b/contracts/WrappedExternalBribe.sol @@ -130,7 +130,12 @@ contract WrappedExternalBribe { prevRewards.timestamp = _nextEpochStart; (, _prevSupply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(_nextEpochStart + DURATION)); - prevRewards.balance = _prevBal * tokenRewardsPerEpoch[token][_nextEpochStart] / _prevSupply; + if (_prevSupply == 0) { + _prevSupply = 1; + prevRewards.balance = 0; + } else { + prevRewards.balance = _prevBal * tokenRewardsPerEpoch[token][_nextEpochStart] / _prevSupply; + } } } @@ -140,7 +145,9 @@ contract WrappedExternalBribe { if (block.timestamp > _lastEpochEnd && _startTimestamp < _lastEpochEnd) { (, _prevSupply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(_lastEpochEnd)); - reward += _prevBal * tokenRewardsPerEpoch[token][_lastEpochStart] / _prevSupply; + if (_prevSupply > 0) { + reward += _prevBal * tokenRewardsPerEpoch[token][_lastEpochStart] / _prevSupply; + } } return reward; diff --git a/test/Pair.t.sol b/test/Pair.t.sol index 0e0657de..05d80e3d 100644 --- a/test/Pair.t.sol +++ b/test/Pair.t.sol @@ -422,7 +422,6 @@ contract PairTest is BaseTest { assertEq(xbribe.balanceOf(1), uint256(voter.votes(1, address(pair)))); vm.warp(block.timestamp + 1 weeks); - voter.vote(4, pools, weights); // TODO: remove this temp fix for zero votes in pools voter.reset(1); assertLt(voter.usedWeights(1), escrow.balanceOfNFT(1)); assertEq(voter.usedWeights(1), 0); @@ -723,7 +722,7 @@ contract PairTest is BaseTest { gaugeClaimRewardsAfterExpiry(); address[] memory bribes_ = new address[](1); - bribes_[0] = address(xbribe); + bribes_[0] = address(wxbribe); address[][] memory rewards = new address[][](1); address[] memory reward = new address[](1); reward[0] = address(DAI); From c7a8893dc9d1b4a3d14666010aacffd952553373 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 24 Mar 2023 10:10:41 +0800 Subject: [PATCH 127/156] fix: remove always true if statement --- contracts/WrappedExternalBribe.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/WrappedExternalBribe.sol b/contracts/WrappedExternalBribe.sol index c86d22e9..e6432d9c 100644 --- a/contracts/WrappedExternalBribe.sol +++ b/contracts/WrappedExternalBribe.sol @@ -145,9 +145,7 @@ contract WrappedExternalBribe { if (block.timestamp > _lastEpochEnd && _startTimestamp < _lastEpochEnd) { (, _prevSupply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(_lastEpochEnd)); - if (_prevSupply > 0) { - reward += _prevBal * tokenRewardsPerEpoch[token][_lastEpochStart] / _prevSupply; - } + reward += _prevBal * tokenRewardsPerEpoch[token][_lastEpochStart] / _prevSupply; } return reward; From bc04e4e45dd5bd01bc9847a2448f5335a9995064 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 28 Mar 2023 19:06:34 +0800 Subject: [PATCH 128/156] feat: add test cases for trading fees directed to tank / bribe contracts --- test/FeesToBribes.t.sol | 176 +++++++++++++++++++++++++++++++++++++++ test/utils/TestOwner.sol | 4 + 2 files changed, 180 insertions(+) create mode 100644 test/FeesToBribes.t.sol diff --git a/test/FeesToBribes.t.sol b/test/FeesToBribes.t.sol new file mode 100644 index 00000000..f1408727 --- /dev/null +++ b/test/FeesToBribes.t.sol @@ -0,0 +1,176 @@ +// 1:1 with Hardhat test +pragma solidity 0.8.13; + +import "./BaseTest.sol"; + +contract FeesToBribesTest is BaseTest { + VotingEscrow escrow; + GaugeFactory gaugeFactory; + BribeFactory bribeFactory; + WrappedExternalBribeFactory wxbribeFactory; + Voter voter; + ExternalBribe xbribe; + WrappedExternalBribe wxbribe; + + function setUp() public { + deployOwners(); + deployCoins(); + mintStables(); + uint256[] memory amounts = new uint256[](3); + amounts[0] = 2e25; + amounts[1] = 1e25; + amounts[2] = 1e25; + mintFlow(owners, amounts); + + VeArtProxy artProxy = new VeArtProxy(); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); + + deployPairFactoryAndRouter(); + deployVoter(); + factory.setFee(true, 2); // 2 bps = 0.02% + deployPairWithOwner(address(owner)); + mintPairFraxUsdcWithOwner(address(owner)); + } + + function deployVoter() public { + gaugeFactory = new GaugeFactory(); + bribeFactory = new BribeFactory(); + wxbribeFactory = new WrappedExternalBribeFactory(); + + voter = new Voter( + address(escrow), + address(factory), + address(gaugeFactory), + address(bribeFactory), + address(wxbribeFactory) + ); + + escrow.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + } + + function testSwapAndFeesSentToTankWithoutGauge() public { + Router.route[] memory routes = new Router.route[](1); + routes[0] = Router.route(address(USDC), address(FRAX), true); + + assertEq( + router.getAmountsOut(USDC_1, routes)[1], + pair.getAmountOut(USDC_1, address(USDC)) + ); + + uint256[] memory assertedOutput = router.getAmountsOut(USDC_1, routes); + USDC.approve(address(router), USDC_1); + router.swapExactTokensForTokens( + USDC_1, + assertedOutput[1], + routes, + address(owner), + block.timestamp + ); + vm.warp(block.timestamp + 1801); + vm.roll(block.number + 1); + address tank = pair.tank(); + assertEq(USDC.balanceOf(tank), 200); // 0.01% -> 0.02% + } + + function testNonPairFactoryOwnerCannotSetTank() public { + vm.expectRevert(abi.encodePacked("Ownable: caller is not the owner")); + owner2.setTank(address(factory), address(owner)); + } + + function testPairFactoryOwnerCanSetTank() public { + owner.setTank(address(factory), address(owner2)); + assertEq(factory.tank(), address(owner2)); + } + + function testNonPairFactoryOwnerCannotChangeFees() public { + vm.expectRevert(abi.encodePacked("Ownable: caller is not the owner")); + owner2.setFee(address(factory), true, 2); + } + + function testPairFactoryOwnerCannotSetFeeAboveMax() public { + vm.expectRevert(abi.encodePacked("fee too high")); + factory.setFee(true, 51); // 6 bps = 0.06% + } + + function testPairFactoryOwnerCanChangeFeesAndClaim() public { + factory.setFee(true, 3); // 3 bps = 0.03% + + Router.route[] memory routes = new Router.route[](1); + routes[0] = Router.route(address(USDC), address(FRAX), true); + + assertEq( + router.getAmountsOut(USDC_1, routes)[1], + pair.getAmountOut(USDC_1, address(USDC)) + ); + + uint256[] memory assertedOutput = router.getAmountsOut(USDC_1, routes); + USDC.approve(address(router), USDC_1); + router.swapExactTokensForTokens( + USDC_1, + assertedOutput[1], + routes, + address(owner), + block.timestamp + ); + vm.warp(block.timestamp + 1801); + vm.roll(block.number + 1); + address tank = pair.tank(); + assertEq(USDC.balanceOf(tank), 300); // 0.01% -> 0.02% + } + + function createLock() public { + FLOW.approve(address(escrow), 5e17); + escrow.create_lock(5e17, FOUR_YEARS); + vm.roll(block.number + 1); // fwd 1 block because escrow.balanceOfNFT() returns 0 in same block + assertGt(escrow.balanceOfNFT(1), 495063075414519385); + assertEq(FLOW.balanceOf(address(escrow)), 5e17); + } + + function testSwapAndClaimFees() public { + createLock(); + vm.warp(block.timestamp + 1 weeks); + + voter.createGauge(address(pair)); + address gaugeAddress = voter.gauges(address(pair)); + address xBribeAddress = voter.external_bribes(gaugeAddress); + xbribe = ExternalBribe(xBribeAddress); + + wxbribe = WrappedExternalBribe( + wxbribeFactory.oldBribeToNew(address(xbribe)) + ); + Router.route[] memory routes = new Router.route[](1); + routes[0] = Router.route(address(USDC), address(FRAX), true); + + assertEq( + router.getAmountsOut(USDC_1, routes)[1], + pair.getAmountOut(USDC_1, address(USDC)) + ); + + uint256[] memory assertedOutput = router.getAmountsOut(USDC_1, routes); + USDC.approve(address(router), USDC_1); + router.swapExactTokensForTokens( + USDC_1, + assertedOutput[1], + routes, + address(owner), + block.timestamp + ); + + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 5000; + voter.vote(1, pools, weights); + + vm.warp(block.timestamp + 1 weeks); + + assertEq(USDC.balanceOf(address(wxbribe)), 200); // 0.01% -> 0.02% + uint256 b = USDC.balanceOf(address(owner)); + address[] memory rewards = new address[](1); + rewards[0] = address(USDC); + wxbribe.getReward(1, rewards); + assertGt(USDC.balanceOf(address(owner)), b); + } +} diff --git a/test/utils/TestOwner.sol b/test/utils/TestOwner.sol index 50296da7..2c20294d 100644 --- a/test/utils/TestOwner.sol +++ b/test/utils/TestOwner.sol @@ -44,6 +44,10 @@ contract TestOwner { PairFactory(_factory).setFee(_stable, _fee); } + function setTank(address _factory, address _tank) public { + PairFactory(_factory).setTank(_tank); + } + /*////////////////////////////////////////////////////////////// Router //////////////////////////////////////////////////////////////*/ From 43113aea802cb4d270c50c5e393d962619fdf71d Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 20 Apr 2023 12:38:25 +0800 Subject: [PATCH 129/156] fix: add wrapped bribe --- contracts/WrappedBribe.sol | 195 ++++++++++ contracts/factories/WrappedBribeFactory.sol | 28 ++ test/WrappedBribes.t.sol | 398 ++++++++++++++++++++ 3 files changed, 621 insertions(+) create mode 100644 contracts/WrappedBribe.sol create mode 100644 contracts/factories/WrappedBribeFactory.sol create mode 100644 test/WrappedBribes.t.sol diff --git a/contracts/WrappedBribe.sol b/contracts/WrappedBribe.sol new file mode 100644 index 00000000..938c10f8 --- /dev/null +++ b/contracts/WrappedBribe.sol @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import 'openzeppelin-contracts/contracts/utils/math/Math.sol'; +import 'contracts/ExternalBribe.sol'; +import 'contracts/interfaces/IERC20.sol'; +import 'contracts/interfaces/IGauge.sol'; +import 'contracts/interfaces/IVoter.sol'; +import 'contracts/interfaces/IVotingEscrow.sol'; + +// Bribes pay out rewards for a given pool based on the votes that were received from the user (goes hand in hand with Voter.vote()) +contract WrappedBribe { + address public immutable voter; + address public immutable _ve; + ExternalBribe public underlying_bribe; + + uint internal constant DURATION = 7 days; // rewards are released over the voting period + uint internal constant MAX_REWARD_TOKENS = 16; + + mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch; + mapping(address => uint) public periodFinish; + mapping(address => mapping(uint => uint)) public lastEarn; + + address[] public rewards; + mapping(address => bool) public isReward; + + /// @notice A checkpoint for marking balance + struct RewardCheckpoint { + uint timestamp; + uint balance; + } + + event NotifyReward(address indexed from, address indexed reward, uint epoch, uint amount); + event ClaimRewards(address indexed from, address indexed reward, uint amount); + + constructor(address _voter, address _old_bribe) { + voter = _voter; + _ve = IVoter(_voter)._ve(); + underlying_bribe = ExternalBribe(_old_bribe); + + for (uint i; i < underlying_bribe.rewardsListLength(); i++) { + address underlying_reward = underlying_bribe.rewards(i); + if (underlying_reward != address(0)) { + isReward[underlying_reward] = true; + rewards.push(underlying_reward); + } + } + } + + // simple re-entrancy check + uint internal _unlocked = 1; + modifier lock() { + require(_unlocked == 1); + _unlocked = 2; + _; + _unlocked = 1; + } + + function _bribeStart(uint timestamp) internal pure returns (uint) { + return timestamp - (timestamp % (7 days)); + } + + function getEpochStart(uint timestamp) public pure returns (uint) { + uint bribeStart = _bribeStart(timestamp); + uint bribeEnd = bribeStart + DURATION; + return timestamp < bribeEnd ? bribeStart : bribeStart + 7 days; + } + + function rewardsListLength() external view returns (uint) { + return rewards.length; + } + + // returns the last time the reward was modified or periodFinish if the reward has ended + function lastTimeRewardApplicable(address token) public view returns (uint) { + return Math.min(block.timestamp, periodFinish[token]); + } + + // allows a user to claim rewards for a given token + function getReward(uint tokenId, address[] memory tokens) external lock { + require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, tokenId)); + for (uint i = 0; i < tokens.length; i++) { + uint _reward = earned(tokens[i], tokenId); + lastEarn[tokens[i]][tokenId] = block.timestamp; + if (_reward > 0) _safeTransfer(tokens[i], msg.sender, _reward); + + emit ClaimRewards(msg.sender, tokens[i], _reward); + } + } + + // used by Voter to allow batched reward claims + function getRewardForOwner(uint tokenId, address[] memory tokens) external lock { + require(msg.sender == voter); + address _owner = IVotingEscrow(_ve).ownerOf(tokenId); + for (uint i = 0; i < tokens.length; i++) { + uint _reward = earned(tokens[i], tokenId); + lastEarn[tokens[i]][tokenId] = block.timestamp; + if (_reward > 0) _safeTransfer(tokens[i], _owner, _reward); + + emit ClaimRewards(_owner, tokens[i], _reward); + } + } + + function earned(address token, uint tokenId) public view returns (uint) { + if (underlying_bribe.numCheckpoints(tokenId) == 0) { + return 0; + } + + uint reward = 0; + uint _ts = 0; + uint _bal = 0; + uint _supply = 1; + uint _index = 0; + uint _currTs = _bribeStart(lastEarn[token][tokenId]); // take epoch last claimed in as starting point + + _index = underlying_bribe.getPriorBalanceIndex(tokenId, _currTs); + (_ts, _bal) = underlying_bribe.checkpoints(tokenId,_index); + // accounts for case where lastEarn is before first checkpoint + _currTs = Math.max(_currTs, _bribeStart(_ts)); + + // get epochs between current epoch and first checkpoint in same epoch as last claim + uint numEpochs = (_bribeStart(block.timestamp) - _currTs) / DURATION; + + if (numEpochs > 0) { + for (uint256 i = 0; i < numEpochs; i++) { + // get index of last checkpoint in this epoch + _index = underlying_bribe.getPriorBalanceIndex(tokenId, _currTs + DURATION); + // get checkpoint in this epoch + (_ts, _bal) = underlying_bribe.checkpoints(tokenId,_index); + // get supply of last checkpoint in this epoch + (, _supply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(_currTs + DURATION)); + if (_supply != 0) { + reward += _bal * tokenRewardsPerEpoch[token][_currTs] / _supply; + } + _currTs += DURATION; + } + } + + return reward; + } + + function left(address token) external view returns (uint) { + uint adjustedTstamp = getEpochStart(block.timestamp); + return tokenRewardsPerEpoch[token][adjustedTstamp]; + } + + function notifyRewardAmount(address token, uint amount) external lock { + require(amount > 0); + if (!isReward[token]) { + require(IVoter(voter).isWhitelisted(token), "bribe tokens must be whitelisted"); + require(rewards.length < MAX_REWARD_TOKENS, "too many rewards tokens"); + } + // bribes kick in at the start of next bribe period + uint adjustedTstamp = getEpochStart(block.timestamp); + uint epochRewards = tokenRewardsPerEpoch[token][adjustedTstamp]; + + uint256 balanceBefore = IERC20(token).balanceOf(address(this)); + _safeTransferFrom(token, msg.sender, address(this), amount); + uint256 balanceAfter = IERC20(token).balanceOf(address(this)); + + amount = balanceAfter - balanceBefore; + + tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount; + + periodFinish[token] = adjustedTstamp + DURATION; + + if (!isReward[token]) { + isReward[token] = true; + rewards.push(token); + } + + emit NotifyReward(msg.sender, token, adjustedTstamp, amount); + } + + function swapOutRewardToken(uint i, address oldToken, address newToken) external { + require(msg.sender == IVotingEscrow(_ve).team(), 'only team'); + require(rewards[i] == oldToken); + isReward[oldToken] = false; + isReward[newToken] = true; + rewards[i] = newToken; + } + + function _safeTransfer(address token, address to, uint256 value) internal { + require(token.code.length > 0); + (bool success, bytes memory data) = + token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); + require(success && (data.length == 0 || abi.decode(data, (bool)))); + } + + function _safeTransferFrom(address token, address from, address to, uint256 value) internal { + require(token.code.length > 0); + (bool success, bytes memory data) = + token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); + require(success && (data.length == 0 || abi.decode(data, (bool)))); + } +} diff --git a/contracts/factories/WrappedBribeFactory.sol b/contracts/factories/WrappedBribeFactory.sol new file mode 100644 index 00000000..6ba5d250 --- /dev/null +++ b/contracts/factories/WrappedBribeFactory.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import {WrappedBribe} from 'contracts/WrappedBribe.sol'; + +contract WrappedBribeFactory { + address public voter; + mapping(address => address) public oldBribeToNew; + address public last_bribe; + + event VoterSet(address indexed setter, address indexed voter); + + function createBribe(address existing_bribe) external returns (address) { + require( + oldBribeToNew[existing_bribe] == address(0), + "Wrapped bribe already created" + ); + last_bribe = address(new WrappedBribe(voter, existing_bribe)); + oldBribeToNew[existing_bribe] = last_bribe; + return last_bribe; + } + + function setVoter(address _voter) external { + require(voter == address(0), "Already initialized"); + voter = _voter; + emit VoterSet(msg.sender, _voter); + } +} diff --git a/test/WrappedBribes.t.sol b/test/WrappedBribes.t.sol new file mode 100644 index 00000000..91b453b3 --- /dev/null +++ b/test/WrappedBribes.t.sol @@ -0,0 +1,398 @@ +pragma solidity 0.8.13; + +import './BaseTest.sol'; +import "contracts/WrappedBribe.sol"; +import "contracts/factories/WrappedBribeFactory.sol"; +import "forge-std/console2.sol"; + +contract WrappedBribesTest is BaseTest { + VotingEscrow escrow; + GaugeFactory gaugeFactory; + BribeFactory bribeFactory; + WrappedBribeFactory wxbribeFactory; + Voter voter; + RewardsDistributor distributor; + Minter minter; + Gauge gauge; + ExternalBribe xbribe; + WrappedBribe wxbribe; + Gauge gauge2; + ExternalBribe xbribe2; + WrappedBribe wxbribe2; + + function setUp() public { + vm.warp(block.timestamp + 1 weeks); // put some initial time in + + deployOwners(); + deployCoins(); + mintStables(); + uint256[] memory amounts = new uint256[](3); + amounts[0] = 2e25; + amounts[1] = 1e25; + amounts[2] = 1e25; + mintFlow(owners, amounts); + mintLR(owners, amounts); + VeArtProxy artProxy = new VeArtProxy(); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); + deployPairFactoryAndRouter(); + + // deployVoter() + gaugeFactory = new GaugeFactory(); + bribeFactory = new BribeFactory(); + wxbribeFactory = new WrappedBribeFactory(); + voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); + + escrow.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + deployPairWithOwner(address(owner)); + + // deployMinter() + distributor = new RewardsDistributor(address(escrow)); + minter = new Minter(address(voter), address(escrow), address(distributor)); + distributor.setDepositor(address(minter)); + FLOW.setMinter(address(minter)); + address[] memory tokens = new address[](5); + tokens[0] = address(USDC); + tokens[1] = address(FRAX); + tokens[2] = address(DAI); + tokens[3] = address(FLOW); + tokens[4] = address(LR); + voter.initialize(tokens, address(minter)); + + Minter.Claim[] memory claims = new Minter.Claim[](0); + minter.initialMintAndLock(claims, 0); + minter.startActivePeriod(); + + // USDC - FRAX stable + gauge = Gauge(voter.createGauge(address(pair))); + xbribe = ExternalBribe(gauge.external_bribe()); + wxbribe = WrappedBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); + + + // USDC - FRAX stable + gauge2 = Gauge(voter.createGauge(address(pair2))); + xbribe2 = ExternalBribe(gauge2.external_bribe()); + wxbribe2 = WrappedBribe(wxbribeFactory.oldBribeToNew(address(xbribe2))); + + // ve + FLOW.approve(address(escrow), TOKEN_1); + escrow.create_lock(TOKEN_1, FOUR_YEARS); + vm.startPrank(address(owner2)); + FLOW.approve(address(escrow), TOKEN_1); + escrow.create_lock(TOKEN_1, FOUR_YEARS); + vm.warp(block.timestamp + 1); + vm.stopPrank(); + + vm.startPrank(address(owner3)); + FLOW.approve(address(escrow), TOKEN_1); + escrow.create_lock(TOKEN_1, FOUR_YEARS); + vm.warp(block.timestamp + 1); + vm.stopPrank(); + } + + function testOldBribesAreBroken() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(xbribe), TOKEN_1); + xbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd half a week + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = xbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + vm.startPrank(address(voter)); + // once + xbribe.getRewardForOwner(1, rewards); + // twice + xbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post = LR.balanceOf(address(owner)); + assertEq(post - pre, TOKEN_1); + } + + function testWrappedBribesCanClaimOnlyOnce() public { + // Epoch 0 + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd half a week + // Epoch flip + // Epoch 1 starts + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 1: BEFORE checking 1 in bribe"); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1 / 2); + + // Middle of Epoch 1 + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe2), TOKEN_1); + wxbribe2.notifyRewardAmount(address(LR), TOKEN_1); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools2 = new address[](1); + pools2[0] = address(pair2); + uint256[] memory weights2 = new uint256[](1); + weights2[0] = 10000; + voter.vote(1, pools2, weights2); + + + vm.startPrank(address(owner2)); + voter.vote(2, pools2, weights2); + vm.stopPrank(); + + + vm.startPrank(address(owner3)); + voter.vote(3, pools, weights); + vm.stopPrank(); + + // fwd half a week + // Epoch flip + // Epoch 2 starts + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre2 = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 2: BEFORE checking 1 in bribe2"); + uint256 earned2 = wxbribe2.earned(address(LR), 1); + assertEq(earned2, TOKEN_1 / 2); + + console2.log(""); + console2.log("Epoch 2: BEFORE checking 1 in bribe1"); + earned = wxbribe.earned(address(LR), 1); + assertEq(earned, 0); + + // rewards + address[] memory rewards2 = new address[](1); + rewards2[0] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe2.getRewardForOwner(1, rewards2); + uint256 post2 = LR.balanceOf(address(owner)); + // twice + wxbribe2.getRewardForOwner(1, rewards2); + vm.stopPrank(); + + uint256 post_post2 = LR.balanceOf(address(owner)); + assertEq(post_post2, post2); + assertEq(post_post2 - pre2, TOKEN_1 / 2); + + continueEpoch2(); + } + + function continueEpoch2() public { + // Middle of epoch 2 + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + + vm.startPrank(address(owner3)); + voter.vote(3, pools, weights); + vm.stopPrank(); + + epoch3(); + } + + function epoch3() public { + // fwd half a week + // Epoch flip + // Epoch 3 starts + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + + vm.startPrank(address(owner3)); + voter.vote(3, pools, weights); + vm.stopPrank(); + + // not claiming epoch 3 bribes for NFT 3 + epoch4(); + } + + function epoch4() public { + // fwd a week + // Epoch flip + // Epoch 4 + vm.warp(block.timestamp + 1 weeks); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + + voter.vote(1, pools, weights); + + vm.startPrank(address(owner3)); + voter.reset(3); + vm.stopPrank(); + + // Middle of epoch 4 + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 4: BEFORE checking 1"); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, 0); // Existing bug: this is >0 + console2.log(""); + console2.log("Epoch 4: BEFORE checking 2"); + earned = wxbribe.earned(address(LR), 2); + assertEq(earned, TOKEN_1 / 2); + console2.log(""); + console2.log("Epoch 4: BEFORE checking 3"); + earned = wxbribe.earned(address(LR), 3); + assertEq(earned, TOKEN_1 * 3); + + epoch5(); + } + + function epoch5() public { + // fwd half a week + // Epoch flip + // Epoch 5 + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 5: BEFORE checking 1"); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1); + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1); + } + + function testWrappedBribesCanClaimOnlyOnceArray() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd half a week + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + // rewards + address[] memory rewards = new address[](2); + rewards[0] = address(LR); + rewards[1] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1 / 2); + } +} \ No newline at end of file From 21a9c675f31644a75c880741e8743c516287c02e Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 20 Apr 2023 12:39:10 +0800 Subject: [PATCH 130/156] fix: add cases in wrapped external bribe --- test/WrappedExternalBribes.t.sol | 196 +++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/test/WrappedExternalBribes.t.sol b/test/WrappedExternalBribes.t.sol index a2284db4..445048ba 100644 --- a/test/WrappedExternalBribes.t.sol +++ b/test/WrappedExternalBribes.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.13; import './BaseTest.sol'; import "contracts/WrappedExternalBribe.sol"; import "contracts/factories/WrappedExternalBribeFactory.sol"; +import "forge-std/console2.sol"; contract WrappedExternalBribesTest is BaseTest { VotingEscrow escrow; @@ -15,6 +16,9 @@ contract WrappedExternalBribesTest is BaseTest { Gauge gauge; ExternalBribe xbribe; WrappedExternalBribe wxbribe; + Gauge gauge2; + ExternalBribe xbribe2; + WrappedExternalBribe wxbribe2; function setUp() public { vm.warp(block.timestamp + 1 weeks); // put some initial time in @@ -65,6 +69,12 @@ contract WrappedExternalBribesTest is BaseTest { xbribe = ExternalBribe(gauge.external_bribe()); wxbribe = WrappedExternalBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); + + // USDC - FRAX stable + gauge2 = Gauge(voter.createGauge(address(pair2))); + xbribe2 = ExternalBribe(gauge2.external_bribe()); + wxbribe2 = WrappedExternalBribe(wxbribeFactory.oldBribeToNew(address(xbribe2))); + // ve FLOW.approve(address(escrow), TOKEN_1); escrow.create_lock(TOKEN_1, FOUR_YEARS); @@ -73,6 +83,12 @@ contract WrappedExternalBribesTest is BaseTest { escrow.create_lock(TOKEN_1, FOUR_YEARS); vm.warp(block.timestamp + 1); vm.stopPrank(); + + vm.startPrank(address(owner3)); + FLOW.approve(address(escrow), TOKEN_1); + escrow.create_lock(TOKEN_1, FOUR_YEARS); + vm.warp(block.timestamp + 1); + vm.stopPrank(); } function testOldBribesAreBroken() public { @@ -116,6 +132,7 @@ contract WrappedExternalBribesTest is BaseTest { } function testWrappedBribesCanClaimOnlyOnce() public { + // Epoch 0 vm.warp(block.timestamp + 1 weeks / 2); // create a bribe @@ -134,9 +151,13 @@ contract WrappedExternalBribesTest is BaseTest { vm.stopPrank(); // fwd half a week + // Epoch flip + // Epoch 1 starts vm.warp(block.timestamp + 1 weeks / 2); uint256 pre = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 1: BEFORE checking 1 in bribe"); uint256 earned = wxbribe.earned(address(LR), 1); assertEq(earned, TOKEN_1 / 2); @@ -155,6 +176,181 @@ contract WrappedExternalBribesTest is BaseTest { uint256 post_post = LR.balanceOf(address(owner)); assertEq(post_post, post); assertEq(post_post - pre, TOKEN_1 / 2); + + // Middle of Epoch 1 + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe2), TOKEN_1); + wxbribe2.notifyRewardAmount(address(LR), TOKEN_1); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools2 = new address[](1); + pools2[0] = address(pair2); + uint256[] memory weights2 = new uint256[](1); + weights2[0] = 10000; + voter.vote(1, pools2, weights2); + + + vm.startPrank(address(owner2)); + voter.vote(2, pools2, weights2); + vm.stopPrank(); + + + vm.startPrank(address(owner3)); + voter.vote(3, pools, weights); + vm.stopPrank(); + + // fwd half a week + // Epoch flip + // Epoch 2 starts + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre2 = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 2: BEFORE checking 1 in bribe2"); + uint256 earned2 = wxbribe2.earned(address(LR), 1); + assertEq(earned2, TOKEN_1 / 2); + + console2.log(""); + console2.log("Epoch 2: BEFORE checking 1 in bribe1"); + earned = wxbribe.earned(address(LR), 1); + assertEq(earned, 0); + + // rewards + address[] memory rewards2 = new address[](1); + rewards2[0] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe2.getRewardForOwner(1, rewards2); + uint256 post2 = LR.balanceOf(address(owner)); + // twice + wxbribe2.getRewardForOwner(1, rewards2); + vm.stopPrank(); + + uint256 post_post2 = LR.balanceOf(address(owner)); + assertEq(post_post2, post2); + assertEq(post_post2 - pre2, TOKEN_1 / 2); + + continueEpoch2(); + } + + function continueEpoch2() public { + // Middle of epoch 2 + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + + vm.startPrank(address(owner3)); + voter.vote(3, pools, weights); + vm.stopPrank(); + + epoch3(); + } + + function epoch3() public { + // fwd half a week + // Epoch flip + // Epoch 3 starts + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + + vm.startPrank(address(owner3)); + voter.vote(3, pools, weights); + vm.stopPrank(); + + // not claiming epoch 3 bribes for NFT 3 + epoch4(); + } + + function epoch4() public { + // fwd a week + // Epoch flip + // Epoch 4 + vm.warp(block.timestamp + 1 weeks); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + + voter.vote(1, pools, weights); + + vm.startPrank(address(owner3)); + voter.reset(3); + vm.stopPrank(); + + // Middle of epoch 4 + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 4: BEFORE checking 1"); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, 0); // Existing bug: this is >0 + console2.log(""); + console2.log("Epoch 4: BEFORE checking 2"); + uint256 earned2 = wxbribe.earned(address(LR), 2); + assertEq(earned2, TOKEN_1 / 2); + console2.log(""); + console2.log("Epoch 4: BEFORE checking 3"); + earned = wxbribe.earned(address(LR), 3); + assertEq(earned, TOKEN_1 * 3); // OK + + epoch5(); + } + + function epoch5() public { + // fwd half a week + // Epoch flip + // Epoch 5 + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + console2.log(""); + console2.log("Epoch 5: BEFORE checking 1"); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1); + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1); } function testWrappedBribesCanClaimOnlyOnceArray() public { From 735ab08ea0e46a8ff95ac9cd2b3dde345c0a797d Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 20 Apr 2023 12:49:57 +0800 Subject: [PATCH 131/156] feat: add handle left over bribes --- contracts/WrappedBribe.sol | 41 ++++++++++ test/WrappedBribes.t.sol | 155 +++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) diff --git a/contracts/WrappedBribe.sol b/contracts/WrappedBribe.sol index 938c10f8..007f27db 100644 --- a/contracts/WrappedBribe.sol +++ b/contracts/WrappedBribe.sol @@ -171,6 +171,47 @@ contract WrappedBribe { emit NotifyReward(msg.sender, token, adjustedTstamp, amount); } + // This is an external function that can only be called by teams to handle unclaimed rewards due to zero vote + function handleLeftOverRewards(uint epochTimestamp, address[] memory tokens) external { + require(msg.sender == IVotingEscrow(_ve).team(), "only team"); + + // require that supply of that epoch to be ZERO + uint epochStart = getEpochStart(epochTimestamp); + (_ts, _supply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(epochStart + DURATION)); + if (epochStart + DURATION > _bribeStart(_ts)) { + require(_supply == 0, "this epoch has votes"); + } + + // do sth like notifyRewardAmount + uint length = tokens.length; + for (uint i = 0; i < length;) { + // check bribe amount + uint previousEpochRewards = tokenRewardsPerEpoch[tokens[i]][epochStart]; + require(previousEpochRewards != 0, "no bribes for this epoch"); + + // get timestamp of current epoch + uint adjustedTstamp = getEpochStart(block.timestamp); + + // get notified reward of current epoch + uint currentEpochRewards = tokenRewardsPerEpoch[tokens[i]][adjustedTstamp]; + + // add previous unclaimed rewards to current epoch + tokenRewardsPerEpoch[tokens[i]][adjustedTstamp] = currentEpochRewards + previousEpochRewards; + + // remove token rewards from previous epoch + tokenRewardsPerEpoch[tokens[i]][epochStart] = 0; + + // amend period finish + periodFinish[tokens[i]] = adjustedTstamp + DURATION; + + emit HandleLeftOverRewards(tokens[i], epochStart, adjustedTstamp, previousEpochRewards); + + unchecked { + ++i; + } + } + } + function swapOutRewardToken(uint i, address oldToken, address newToken) external { require(msg.sender == IVotingEscrow(_ve).team(), 'only team'); require(rewards[i] == oldToken); diff --git a/test/WrappedBribes.t.sol b/test/WrappedBribes.t.sol index 91b453b3..a35464a8 100644 --- a/test/WrappedBribes.t.sol +++ b/test/WrappedBribes.t.sol @@ -395,4 +395,159 @@ contract WrappedBribesTest is BaseTest { assertEq(post_post, post); assertEq(post_post - pre, TOKEN_1 / 2); } + + function testBribesCanClaimLeftOverRewardAfterBeingHandled() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // fwd half a week + uint epochTimestamp = block.timestamp; + vm.warp(block.timestamp + 1 weeks / 2); + + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + wxbribe.handleLeftOverRewards(epochTimestamp, rewards); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd a week + vm.warp(block.timestamp + 1 weeks); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1 / 2); + } + + function testBribesCanClaimLeftOverRewardAfterBeingHandledPlusAddingMoreBribes() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // fwd half a week + uint epochTimestamp = block.timestamp; + vm.warp(block.timestamp + 1 weeks / 2); + + // add more bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + wxbribe.handleLeftOverRewards(epochTimestamp, rewards); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd a week + vm.warp(block.timestamp + 1 weeks); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1); + } + + function testBribesCanClaimLeftOverRewardAfterBeingHandledAfterSeveralEpochs() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // fwd half a week + uint epochTimestamp = block.timestamp; + vm.warp(block.timestamp + 1 weeks / 2); + + // add more bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd a week + vm.warp(block.timestamp + 3 weeks); + + wxbribe.handleLeftOverRewards(epochTimestamp, rewards); + + vm.warp(block.timestamp + 1 weeks); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1); + } + } \ No newline at end of file From b6925e38bfa5699cbb5177cdc4be1c4b12354f73 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 20 Apr 2023 12:54:57 +0800 Subject: [PATCH 132/156] fix: add events --- contracts/WrappedBribe.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/WrappedBribe.sol b/contracts/WrappedBribe.sol index 007f27db..f53ce105 100644 --- a/contracts/WrappedBribe.sol +++ b/contracts/WrappedBribe.sol @@ -32,6 +32,7 @@ contract WrappedBribe { event NotifyReward(address indexed from, address indexed reward, uint epoch, uint amount); event ClaimRewards(address indexed from, address indexed reward, uint amount); + event HandleLeftOverRewards(address indexed reward, uint originalEpoch, uint updatedEpoch, uint amount); constructor(address _voter, address _old_bribe) { voter = _voter; @@ -177,7 +178,7 @@ contract WrappedBribe { // require that supply of that epoch to be ZERO uint epochStart = getEpochStart(epochTimestamp); - (_ts, _supply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(epochStart + DURATION)); + (uint _ts, uint _supply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(epochStart + DURATION)); if (epochStart + DURATION > _bribeStart(_ts)) { require(_supply == 0, "this epoch has votes"); } From 5eac3402bdeae7ece9b623baac148e8163bfdc04 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 23 Apr 2023 22:13:38 +0800 Subject: [PATCH 133/156] feat: add updateRewardAmount in wrapped bribe contract for balance discrepancy --- contracts/WrappedBribe.sol | 46 +++++++++++++++++++++- test/WrappedBribes.t.sol | 80 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/contracts/WrappedBribe.sol b/contracts/WrappedBribe.sol index f53ce105..bc9ce2a0 100644 --- a/contracts/WrappedBribe.sol +++ b/contracts/WrappedBribe.sol @@ -23,6 +23,7 @@ contract WrappedBribe { address[] public rewards; mapping(address => bool) public isReward; + mapping(address => uint) public tokenRewardBalance; /// @notice A checkpoint for marking balance struct RewardCheckpoint { @@ -79,10 +80,17 @@ contract WrappedBribe { // allows a user to claim rewards for a given token function getReward(uint tokenId, address[] memory tokens) external lock { require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, tokenId)); + + uint256 balanceBefore; + for (uint i = 0; i < tokens.length; i++) { uint _reward = earned(tokens[i], tokenId); lastEarn[tokens[i]][tokenId] = block.timestamp; - if (_reward > 0) _safeTransfer(tokens[i], msg.sender, _reward); + if (_reward > 0) { + balanceBefore = IERC20(tokens[i]).balanceOf(address(this)); + _safeTransfer(tokens[i], msg.sender, _reward); + tokenRewardBalance[tokens[i]] -= balanceBefore - IERC20(tokens[i]).balanceOf(address(this)); + } emit ClaimRewards(msg.sender, tokens[i], _reward); } @@ -92,10 +100,17 @@ contract WrappedBribe { function getRewardForOwner(uint tokenId, address[] memory tokens) external lock { require(msg.sender == voter); address _owner = IVotingEscrow(_ve).ownerOf(tokenId); + + uint256 balanceBefore; + for (uint i = 0; i < tokens.length; i++) { uint _reward = earned(tokens[i], tokenId); lastEarn[tokens[i]][tokenId] = block.timestamp; - if (_reward > 0) _safeTransfer(tokens[i], _owner, _reward); + if (_reward > 0) { + balanceBefore = IERC20(tokens[i]).balanceOf(address(this)); + _safeTransfer(tokens[i], _owner, _reward); + tokenRewardBalance[tokens[i]] -= balanceBefore - IERC20(tokens[i]).balanceOf(address(this)); + } emit ClaimRewards(_owner, tokens[i], _reward); } @@ -161,6 +176,7 @@ contract WrappedBribe { amount = balanceAfter - balanceBefore; tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount; + tokenRewardBalance[token] += amount; periodFinish[token] = adjustedTstamp + DURATION; @@ -172,6 +188,32 @@ contract WrappedBribe { emit NotifyReward(msg.sender, token, adjustedTstamp, amount); } + function updateRewardAmount(address[] memory tokens) external lock { + uint256 length = tokens.length; + uint256 adjustedTstamp = getEpochStart(block.timestamp); + + uint256 rewardBalance; + uint256 difference; + + for (uint256 i = 0; i < length;) { + rewardBalance = tokenRewardBalance[tokens[i]]; + difference = IERC20(tokens[i]).balanceOf(address(this)) - rewardBalance; + + if (difference != 0) { + tokenRewardsPerEpoch[tokens[i]][adjustedTstamp] += difference; + tokenRewardBalance[tokens[i]] = rewardBalance + difference; + + periodFinish[tokens[i]] = adjustedTstamp + DURATION; + + emit NotifyReward(msg.sender, tokens[i], adjustedTstamp, difference); + } + + unchecked { + ++i; + } + } + } + // This is an external function that can only be called by teams to handle unclaimed rewards due to zero vote function handleLeftOverRewards(uint epochTimestamp, address[] memory tokens) external { require(msg.sender == IVotingEscrow(_ve).team(), "only team"); diff --git a/test/WrappedBribes.t.sol b/test/WrappedBribes.t.sol index a35464a8..de4dd293 100644 --- a/test/WrappedBribes.t.sol +++ b/test/WrappedBribes.t.sol @@ -550,4 +550,84 @@ contract WrappedBribesTest is BaseTest { assertEq(post_post - pre, TOKEN_1); } + function testCanUpdateRewardAmountWithBalanceDiscrepancy() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // transfer LR tokens to wxbribe + LR.transfer(address(wxbribe), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // try to get reward for owner + address[] memory tokens = new address[](1); + tokens[0] = address(LR); + + uint256 balance1 = LR.balanceOf(address(owner)); + uint256 pre_pre_earned = wxbribe.earned(address(LR), 1); + assertEq(pre_pre_earned, 0); + vm.startPrank(address(voter)); + wxbribe.getRewardForOwner(1, tokens); + vm.stopPrank(); + + uint256 balance2 = LR.balanceOf(address(owner)); + assertEq(balance2 - balance1, 0); + uint256 pre_earned = wxbribe.earned(address(LR), 1); + assertEq(pre_earned, 0); + + // update reward amount before epoch flip + wxbribe.updateRewardAmount(tokens); + + // fwd half a week + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, tokens); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, tokens); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1 / 2); + } + + function testCannotUpdateRewardAmountWithoutBalanceDiscrepancy() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + uint256 actualBalance1 = LR.balanceOf(address(wxbribe)); + assertEq(actualBalance1, TOKEN_1); + + uint256 accountBalance1 = wxbribe.tokenRewardBalance(address(LR)); + assertEq(accountBalance1, TOKEN_1); + + // try to update reward amount + address[] memory tokens = new address[](1); + tokens[0] = address(LR); + wxbribe.updateRewardAmount(tokens); + + uint256 actualBalance2 = LR.balanceOf(address(wxbribe)); + assertEq(actualBalance2, TOKEN_1); + + uint256 accountBalance2 = wxbribe.tokenRewardBalance(address(LR)); + assertEq(accountBalance2, TOKEN_1); + } } \ No newline at end of file From 9adbcbbc0157f669833817876835d0f23f8baa54 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 23 Apr 2023 22:36:17 +0800 Subject: [PATCH 134/156] fix: add test case for updateRewardAmount --- test/WrappedBribes.t.sol | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/test/WrappedBribes.t.sol b/test/WrappedBribes.t.sol index de4dd293..f4b5e09a 100644 --- a/test/WrappedBribes.t.sol +++ b/test/WrappedBribes.t.sol @@ -630,4 +630,76 @@ contract WrappedBribesTest is BaseTest { uint256 accountBalance2 = wxbribe.tokenRewardBalance(address(LR)); assertEq(accountBalance2, TOKEN_1); } + + function testCanUpdateRewardAmountCorrectlyAfterClaiming() public { + vm.warp(block.timestamp + 1 weeks / 2); + + // create a bribe + LR.approve(address(wxbribe), TOKEN_1); + wxbribe.notifyRewardAmount(address(LR), TOKEN_1); + + // transfer LR token to wxbribe + LR.transfer(address(wxbribe), TOKEN_1); + + // vote + address[] memory pools = new address[](1); + pools[0] = address(pair); + uint256[] memory weights = new uint256[](1); + weights[0] = 10000; + voter.vote(1, pools, weights); + + vm.startPrank(address(owner2)); + voter.vote(2, pools, weights); + vm.stopPrank(); + + // fwd half a week + vm.warp(block.timestamp + 1 weeks / 2); + + uint256 pre = LR.balanceOf(address(owner)); + uint256 earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + // rewards + address[] memory rewards = new address[](1); + rewards[0] = address(LR); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + uint256 post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + uint256 post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1 / 2); + + uint256 accountBalance1 = wxbribe.tokenRewardBalance(address(LR)); + + // update reward amount before epoch flip + wxbribe.updateRewardAmount(rewards); + + uint256 accountBalance2 = wxbribe.tokenRewardBalance(address(LR)); + assertEq(accountBalance2 - accountBalance1, TOKEN_1); + + // epoch flip + vm.warp(block.timestamp + 1 weeks); + + pre = LR.balanceOf(address(owner)); + earned = wxbribe.earned(address(LR), 1); + assertEq(earned, TOKEN_1 / 2); + + vm.startPrank(address(voter)); + // once + wxbribe.getRewardForOwner(1, rewards); + post = LR.balanceOf(address(owner)); + // twice + wxbribe.getRewardForOwner(1, rewards); + vm.stopPrank(); + + post_post = LR.balanceOf(address(owner)); + assertEq(post_post, post); + assertEq(post_post - pre, TOKEN_1 / 2); + } } \ No newline at end of file From 41c2a97d07fef7e29938e9dc862ec4e21c86b53e Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 25 Apr 2023 21:43:02 +0800 Subject: [PATCH 135/156] feat: add autobribe --- contracts/AutoBribe.sol | 138 ++++++++++++++++++++ contracts/factories/WrappedBribeFactory.sol | 21 +++ test/WrappedBribes.t.sol | 3 +- 3 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 contracts/AutoBribe.sol diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol new file mode 100644 index 00000000..a7636987 --- /dev/null +++ b/contracts/AutoBribe.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: MIT + +import "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; +import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import "openzeppelin-contracts/contracts/utils/math/SafeMath.sol"; +import "openzeppelin-contracts/contracts/access/Ownable.sol"; +import "openzeppelin-contracts/contracts/utils/Context.sol"; +import "openzeppelin-contracts/contracts/utils/Address.sol"; +import {WrappedBribe} from 'contracts/WrappedBribe.sol'; + +pragma solidity 0.8.13; + +// the purpose of this contract is to allow the projects to deposit bribes that will bribe their pools for a period of time +// they will need to know the appropriate wrappedExternalBribe contract address +// they will need to set up a public keeper, anyone can send the bribes +// bribes are divided evenly into the amount of weeks designated when they deposit +// each new deposit, will check for additional bribe tokens that may have been sent to the contract by accident +// each new deposit will make a bribe immediately! +// calling the bribe function is public and is rewarded with a share of the bribe token +// !!!!!!!!!!!this contract only handles a single bribe token, and a single bribe contract!!!!!!!!! + +contract AutoBribe is Ownable { + using SafeERC20 for IERC20; + using SafeMath for uint256; + + address public immutable wBribe; + + address public project; + uint256 public nextWeek; + address[] public bribeTokens; + mapping(address => bool) bribeTokensDeposited; + mapping(address => uint256) bribeTokenToWeeksLeft; + + constructor(address _wBribe, address _team) { + wBribe = _wBribe; + _transferOwnership(_team); + } + + //####USER FUNCTIONS##### + + function depositAll( + address[] memory _bribeTokens, + uint256 _weeks + ) external { + uint256 length = _bribeTokens.length; + for (uint256 i = 0; i < length; ) { + address bribeToken = _bribeTokens[i]; + deposit( + bribeToken, + IERC20(bribeToken).balanceOf(msg.sender), + _weeks + ); + unchecked { + ++i; + } + } + } + + function deposit( + address _bribeToken, + uint256 _amount, + uint256 _weeks + ) public { + require(msg.sender == project, "only the project can bribe"); + require(_amount > 0, "Why are you depositing 0 tokens?"); + require(_weeks > 0, "You have to put at least 1 week"); + IERC20(_bribeToken).safeTransferFrom( + msg.sender, + address(this), + _amount + ); + if (!bribeTokensDeposited[_bribeToken]) { + bribeTokensDeposited[_bribeToken] = true; + bribeTokens.push(_bribeToken); + } + bribeTokenToWeeksLeft[_bribeToken] = _weeks; + } + + function bribe() public { + uint256 length = bribeTokens.length; + address _bribeToken; + for (uint256 i = 0; i < length; ) { + if (block.timestamp >= nextWeek) { + _bribeToken = bribeTokens[i]; + uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; + uint256 bribeAmount = balance(_bribeToken) / weeksLeft; + uint256 gasReward = bribeAmount / 10000; + IERC20(_bribeToken).safeTransferFrom( + address(this), + msg.sender, + gasReward + ); + WrappedBribe(wBribe).notifyRewardAmount(_bribeToken, bribeAmount - gasReward); + bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; + } + unchecked { + ++i; + } + } + + nextWeek = nextWeek + 604800; + } + + function balance(address _bribeToken) public view returns (uint) { + return IERC20(_bribeToken).balanceOf(address(this)); + } + + //####Admin Functions##### + function emptyOut() public { + require(msg.sender == project); + + uint256 length = bribeTokens.length; + uint256 amount; + + for (uint256 i = 0; i < length; ) { + address bribeToken = bribeTokens[i]; + amount = balance(bribeToken); + bribeTokensDeposited[bribeToken] = false; + bribeTokenToWeeksLeft[bribeToken] = 0; + IERC20(bribeToken).safeTransfer(msg.sender, amount); + + unchecked { + ++i; + } + } + } + + function setProject(address _newWallet) public { + require(msg.sender == project || msg.sender == owner()); + project = _newWallet; + } + + function inCaseTokensGetStuck(address _token) external onlyOwner { + require(!bribeTokensDeposited[_token], "!bribeToken"); + uint256 amount = IERC20(_token).balanceOf(address(this)); + IERC20(_token).safeTransfer(msg.sender, amount); + } +} diff --git a/contracts/factories/WrappedBribeFactory.sol b/contracts/factories/WrappedBribeFactory.sol index 6ba5d250..9491b1e6 100644 --- a/contracts/factories/WrappedBribeFactory.sol +++ b/contracts/factories/WrappedBribeFactory.sol @@ -1,15 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; +import {AutoBribe} from 'contracts/AutoBribe.sol'; import {WrappedBribe} from 'contracts/WrappedBribe.sol'; contract WrappedBribeFactory { + address public immutable team; address public voter; mapping(address => address) public oldBribeToNew; + mapping(address => address) public oldBribeToAutoBribe; address public last_bribe; event VoterSet(address indexed setter, address indexed voter); + constructor(address _team) { + team = _team; + } + function createBribe(address existing_bribe) external returns (address) { require( oldBribeToNew[existing_bribe] == address(0), @@ -20,6 +27,20 @@ contract WrappedBribeFactory { return last_bribe; } + function createAutoBribe(address existing_bribe) external returns (address auto_bribe) { + address wBribe = oldBribeToNew[existing_bribe]; + require( + oldBribeToNew[existing_bribe] != address(0), + "Wrapped bribe not yet created" + ); + require( + oldBribeToAutoBribe[existing_bribe] == address(0), + "Auto bribe already created" + ); + auto_bribe = address(new AutoBribe(wBribe, team)); + oldBribeToAutoBribe[existing_bribe] = auto_bribe; + } + function setVoter(address _voter) external { require(voter == address(0), "Already initialized"); voter = _voter; diff --git a/test/WrappedBribes.t.sol b/test/WrappedBribes.t.sol index f4b5e09a..c0490420 100644 --- a/test/WrappedBribes.t.sol +++ b/test/WrappedBribes.t.sol @@ -39,7 +39,7 @@ contract WrappedBribesTest is BaseTest { // deployVoter() gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - wxbribeFactory = new WrappedBribeFactory(); + wxbribeFactory = new WrappedBribeFactory(address(owner)); voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); escrow.setVoter(address(voter)); @@ -308,7 +308,6 @@ contract WrappedBribesTest is BaseTest { // Middle of epoch 4 vm.warp(block.timestamp + 1 weeks / 2); - uint256 pre = LR.balanceOf(address(owner)); console2.log(""); console2.log("Epoch 4: BEFORE checking 1"); uint256 earned = wxbribe.earned(address(LR), 1); From 74f058bebde6041f8da48d83359553296f3db276 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 25 Apr 2023 21:59:43 +0800 Subject: [PATCH 136/156] refactor: reuse declared vairables in WrappedBribeFactory --- contracts/factories/WrappedBribeFactory.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/factories/WrappedBribeFactory.sol b/contracts/factories/WrappedBribeFactory.sol index 9491b1e6..821d0c96 100644 --- a/contracts/factories/WrappedBribeFactory.sol +++ b/contracts/factories/WrappedBribeFactory.sol @@ -30,7 +30,7 @@ contract WrappedBribeFactory { function createAutoBribe(address existing_bribe) external returns (address auto_bribe) { address wBribe = oldBribeToNew[existing_bribe]; require( - oldBribeToNew[existing_bribe] != address(0), + wBribe != address(0), "Wrapped bribe not yet created" ); require( From 35688ed29de7820fb7bc251eb39578402832cdad Mon Sep 17 00:00:00 2001 From: Ceazor <73511897+Ceazor@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:58:04 -0600 Subject: [PATCH 137/156] added seal() --- contracts/AutoBribe.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index a7636987..fd84d71d 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -28,6 +28,7 @@ contract AutoBribe is Ownable { address public project; uint256 public nextWeek; address[] public bribeTokens; + bool sealed; mapping(address => bool) bribeTokensDeposited; mapping(address => uint256) bribeTokenToWeeksLeft; @@ -108,6 +109,7 @@ contract AutoBribe is Ownable { //####Admin Functions##### function emptyOut() public { require(msg.sender == project); + require(!sealed); uint256 length = bribeTokens.length; uint256 amount; @@ -124,6 +126,15 @@ contract AutoBribe is Ownable { } } } + //Allows project to seal the vault making it not possible for them to withdraw their tokens + function seal() public { + require(msg.sender = project); + sealed = true; + } + //Allows Velocimeter to re allow project to withdraw their tokens + function unSeal() public onlyOwner { + sealed = false; + } function setProject(address _newWallet) public { require(msg.sender == project || msg.sender == owner()); From 67a9df8ee9a7de29153610969b14c123445bfd52 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Wed, 26 Apr 2023 09:28:14 +0800 Subject: [PATCH 138/156] feat: add seal() in AutoBribe --- contracts/AutoBribe.sol | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index fd84d71d..1e476b6d 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -6,18 +6,16 @@ import "openzeppelin-contracts/contracts/utils/math/SafeMath.sol"; import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "openzeppelin-contracts/contracts/utils/Context.sol"; import "openzeppelin-contracts/contracts/utils/Address.sol"; -import {WrappedBribe} from 'contracts/WrappedBribe.sol'; +import {WrappedBribe} from "contracts/WrappedBribe.sol"; pragma solidity 0.8.13; // the purpose of this contract is to allow the projects to deposit bribes that will bribe their pools for a period of time -// they will need to know the appropriate wrappedExternalBribe contract address // they will need to set up a public keeper, anyone can send the bribes // bribes are divided evenly into the amount of weeks designated when they deposit -// each new deposit, will check for additional bribe tokens that may have been sent to the contract by accident -// each new deposit will make a bribe immediately! +// each new deposit will NOT make a bribe immediately! // calling the bribe function is public and is rewarded with a share of the bribe token -// !!!!!!!!!!!this contract only handles a single bribe token, and a single bribe contract!!!!!!!!! +// !!!!!!!!!!!this contract handles multiple bribe tokens, and a single bribe contract!!!!!!!!! contract AutoBribe is Ownable { using SafeERC20 for IERC20; @@ -26,6 +24,7 @@ contract AutoBribe is Ownable { address public immutable wBribe; address public project; + bool sealed; uint256 public nextWeek; address[] public bribeTokens; bool sealed; @@ -91,7 +90,10 @@ contract AutoBribe is Ownable { msg.sender, gasReward ); - WrappedBribe(wBribe).notifyRewardAmount(_bribeToken, bribeAmount - gasReward); + WrappedBribe(wBribe).notifyRewardAmount( + _bribeToken, + bribeAmount - gasReward + ); bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; } unchecked { @@ -126,11 +128,24 @@ contract AutoBribe is Ownable { } } } + //Allows project to seal the vault making it not possible for them to withdraw their tokens function seal() public { require(msg.sender = project); sealed = true; } + + //Allows Velocimeter to re allow project to withdraw their tokens + function unSeal() public onlyOwner { + sealed = false; + } + + //Allows project to seal the vault making it not possible for them to withdraw their tokens + function seal() public { + require(msg.sender = project); + sealed = true; + } + //Allows Velocimeter to re allow project to withdraw their tokens function unSeal() public onlyOwner { sealed = false; From e6d693960c59a9f1b3a7a7ee43595430769613fa Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 27 Apr 2023 11:09:30 +0800 Subject: [PATCH 139/156] fix: add identifier for sealed in AutoBribe --- contracts/AutoBribe.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index 1e476b6d..e3b04c10 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -24,7 +24,7 @@ contract AutoBribe is Ownable { address public immutable wBribe; address public project; - bool sealed; + bool public sealed; uint256 public nextWeek; address[] public bribeTokens; bool sealed; From f84f95774731c0583663573579b6a9ecb78b7b75 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Thu, 27 Apr 2023 11:12:40 +0800 Subject: [PATCH 140/156] fix: use non-reserved keyword for variable name in AutoBribe --- contracts/AutoBribe.sol | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index e3b04c10..b50b474a 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -24,7 +24,7 @@ contract AutoBribe is Ownable { address public immutable wBribe; address public project; - bool public sealed; + bool public depositSealed; uint256 public nextWeek; address[] public bribeTokens; bool sealed; @@ -111,8 +111,7 @@ contract AutoBribe is Ownable { //####Admin Functions##### function emptyOut() public { require(msg.sender == project); - require(!sealed); - + require(!depositSealed); uint256 length = bribeTokens.length; uint256 amount; @@ -132,12 +131,12 @@ contract AutoBribe is Ownable { //Allows project to seal the vault making it not possible for them to withdraw their tokens function seal() public { require(msg.sender = project); - sealed = true; + depositSealed = true; } //Allows Velocimeter to re allow project to withdraw their tokens function unSeal() public onlyOwner { - sealed = false; + depositSealed = false; } //Allows project to seal the vault making it not possible for them to withdraw their tokens From d6e0deccb07c7476d069fa01c39a78cf712d8362 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 08:06:21 +0800 Subject: [PATCH 141/156] feat: update AutoBribe --- contracts/AutoBribe.sol | 99 +++++++++---- test/AutoBribe.t.sol | 316 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 389 insertions(+), 26 deletions(-) create mode 100644 test/AutoBribe.t.sol diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index b50b474a..691bf462 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -1,12 +1,10 @@ // SPDX-License-Identifier: MIT -import "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; -import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; -import "openzeppelin-contracts/contracts/utils/math/SafeMath.sol"; import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "openzeppelin-contracts/contracts/utils/Context.sol"; import "openzeppelin-contracts/contracts/utils/Address.sol"; -import {WrappedBribe} from "contracts/WrappedBribe.sol"; +import "contracts/interfaces/IERC20.sol"; +import "contracts/WrappedBribe.sol"; pragma solidity 0.8.13; @@ -18,18 +16,24 @@ pragma solidity 0.8.13; // !!!!!!!!!!!this contract handles multiple bribe tokens, and a single bribe contract!!!!!!!!! contract AutoBribe is Ownable { - using SafeERC20 for IERC20; - using SafeMath for uint256; - address public immutable wBribe; address public project; bool public depositSealed; uint256 public nextWeek; address[] public bribeTokens; - bool sealed; - mapping(address => bool) bribeTokensDeposited; - mapping(address => uint256) bribeTokenToWeeksLeft; + mapping(address => bool) public bribeTokensDeposited; + mapping(address => uint256) public bribeTokenToWeeksLeft; + + event Deposited( + address indexed _bribeToken, + uint256 _amount, + uint256 _weeks + ); + event Bribed(uint256 indexed _timestamp, address _briber); + event EmptiedOut(uint256 indexed _timestamp, address project); + event Sealed(uint256 indexed _timestamp); + event UnSealed(uint256 indexed _timestamp); constructor(address _wBribe, address _team) { wBribe = _wBribe; @@ -64,16 +68,19 @@ contract AutoBribe is Ownable { require(msg.sender == project, "only the project can bribe"); require(_amount > 0, "Why are you depositing 0 tokens?"); require(_weeks > 0, "You have to put at least 1 week"); - IERC20(_bribeToken).safeTransferFrom( - msg.sender, + _safeTransferFrom(_bribeToken, msg.sender, address(this), _amount); + uint256 allowance = IERC20(_bribeToken).allowance( address(this), - _amount + wBribe ); + _safeApprove(_bribeToken, wBribe, allowance + _amount); if (!bribeTokensDeposited[_bribeToken]) { bribeTokensDeposited[_bribeToken] = true; bribeTokens.push(_bribeToken); } - bribeTokenToWeeksLeft[_bribeToken] = _weeks; + bribeTokenToWeeksLeft[_bribeToken] += _weeks; + + emit Deposited(_bribeToken, _amount, _weeks); } function bribe() public { @@ -85,11 +92,7 @@ contract AutoBribe is Ownable { uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; uint256 bribeAmount = balance(_bribeToken) / weeksLeft; uint256 gasReward = bribeAmount / 10000; - IERC20(_bribeToken).safeTransferFrom( - address(this), - msg.sender, - gasReward - ); + _safeTransfer(_bribeToken, msg.sender, gasReward); WrappedBribe(wBribe).notifyRewardAmount( _bribeToken, bribeAmount - gasReward @@ -101,6 +104,8 @@ contract AutoBribe is Ownable { } } + emit Bribed(nextWeek, msg.sender); + nextWeek = nextWeek + 604800; } @@ -110,33 +115,38 @@ contract AutoBribe is Ownable { //####Admin Functions##### function emptyOut() public { - require(msg.sender == project); - require(!depositSealed); + require(msg.sender == project, "only project can empty out"); + require(!depositSealed, "deposit is sealed"); uint256 length = bribeTokens.length; uint256 amount; for (uint256 i = 0; i < length; ) { address bribeToken = bribeTokens[i]; amount = balance(bribeToken); - bribeTokensDeposited[bribeToken] = false; bribeTokenToWeeksLeft[bribeToken] = 0; - IERC20(bribeToken).safeTransfer(msg.sender, amount); + _safeTransfer(bribeToken, msg.sender, amount); unchecked { ++i; } } + + emit EmptiedOut(block.timestamp, project); } //Allows project to seal the vault making it not possible for them to withdraw their tokens function seal() public { - require(msg.sender = project); + require(msg.sender == project, "only project can seal"); depositSealed = true; + + emit Sealed(block.timestamp); } //Allows Velocimeter to re allow project to withdraw their tokens function unSeal() public onlyOwner { depositSealed = false; + + emit UnSealed(block.timestamp); } //Allows project to seal the vault making it not possible for them to withdraw their tokens @@ -151,13 +161,50 @@ contract AutoBribe is Ownable { } function setProject(address _newWallet) public { - require(msg.sender == project || msg.sender == owner()); + require( + msg.sender == project || msg.sender == owner(), + "only project or team" + ); project = _newWallet; } function inCaseTokensGetStuck(address _token) external onlyOwner { require(!bribeTokensDeposited[_token], "!bribeToken"); uint256 amount = IERC20(_token).balanceOf(address(this)); - IERC20(_token).safeTransfer(msg.sender, amount); + _safeTransfer(_token, msg.sender, amount); + } + + function _safeTransfer(address token, address to, uint256 value) internal { + require(token.code.length > 0); + (bool success, bytes memory data) = token.call( + abi.encodeWithSelector(IERC20.transfer.selector, to, value) + ); + require(success && (data.length == 0 || abi.decode(data, (bool)))); + } + + function _safeTransferFrom( + address token, + address from, + address to, + uint256 value + ) internal { + require(token.code.length > 0); + (bool success, bytes memory data) = token.call( + abi.encodeWithSelector( + IERC20.transferFrom.selector, + from, + to, + value + ) + ); + require(success && (data.length == 0 || abi.decode(data, (bool)))); + } + + function _safeApprove(address token, address spender, uint value) internal { + require(token.code.length > 0); + (bool success, bytes memory data) = token.call( + abi.encodeWithSelector(IERC20.approve.selector, spender, value) + ); + require(success && (data.length == 0 || abi.decode(data, (bool)))); } } diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol new file mode 100644 index 00000000..ce8e3d2c --- /dev/null +++ b/test/AutoBribe.t.sol @@ -0,0 +1,316 @@ +pragma solidity 0.8.13; + +import "./BaseTest.sol"; +import "contracts/AutoBribe.sol"; +import "contracts/WrappedBribe.sol"; +import "contracts/factories/WrappedBribeFactory.sol"; +import "forge-std/console2.sol"; + +contract AutoBribeTest is BaseTest { + VotingEscrow escrow; + GaugeFactory gaugeFactory; + BribeFactory bribeFactory; + WrappedBribeFactory wbribeFactory; + Voter voter; + RewardsDistributor distributor; + Minter minter; + Gauge gauge; + ExternalBribe xbribe; + WrappedBribe wbribe; + AutoBribe autoBribe; + Gauge gauge2; + ExternalBribe xbribe2; + WrappedBribe wbribe2; + AutoBribe autoBribe2; + + function setUp() public { + vm.warp(block.timestamp + 1 weeks); // put some initial time in + + deployOwners(); + deployCoins(); + mintStables(); + uint256[] memory amounts = new uint256[](3); + amounts[0] = 2e25; + amounts[1] = 1e25; + amounts[2] = 1e25; + mintFlow(owners, amounts); + mintLR(owners, amounts); + VeArtProxy artProxy = new VeArtProxy(); + escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); + deployPairFactoryAndRouter(); + + // deployVoter() + gaugeFactory = new GaugeFactory(); + bribeFactory = new BribeFactory(); + wbribeFactory = new WrappedBribeFactory(address(owner)); + voter = new Voter( + address(escrow), + address(factory), + address(gaugeFactory), + address(bribeFactory), + address(wbribeFactory) + ); + + escrow.setVoter(address(voter)); + wbribeFactory.setVoter(address(voter)); + factory.setVoter(address(voter)); + deployPairWithOwner(address(owner)); + + // deployMinter() + distributor = new RewardsDistributor(address(escrow)); + minter = new Minter( + address(voter), + address(escrow), + address(distributor) + ); + distributor.setDepositor(address(minter)); + FLOW.setMinter(address(minter)); + address[] memory tokens = new address[](5); + tokens[0] = address(USDC); + tokens[1] = address(FRAX); + tokens[2] = address(DAI); + tokens[3] = address(FLOW); + tokens[4] = address(LR); + voter.initialize(tokens, address(minter)); + + // USDC - FRAX stable + gauge = Gauge(voter.createGauge(address(pair))); + xbribe = ExternalBribe(gauge.external_bribe()); + wbribe = WrappedBribe(wbribeFactory.oldBribeToNew(address(xbribe))); + autoBribe = AutoBribe(wbribeFactory.createAutoBribe(address(xbribe))); + + vm.startPrank(address(owner)); + autoBribe.setProject(address(owner2)); + vm.stopPrank(); + } + + function testSetUpCorrectly() public { + assertEq(autoBribe.owner(), address(owner)); + assertEq(autoBribe.project(), address(owner2)); + assertEq(autoBribe.wBribe(), address(wbribe)); + } + + function testCanDepositAndBribeEveryWeek( + uint256 depositAmountLR, + uint256 depositAmountFLOW, + uint256 depositWeeks + ) public { + vm.assume( + depositAmountLR > depositWeeks && + depositAmountLR <= 1e25 && + depositAmountFLOW > depositWeeks && + depositAmountFLOW <= 1e25 && + depositWeeks > 0 && + depositWeeks < 52 + ); + + vm.warp(block.timestamp + 1 weeks / 2); + + // Project deposit tokens + vm.startPrank(address(owner2)); + LR.approve(address(autoBribe), depositAmountLR); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + + FLOW.approve(address(autoBribe), depositAmountFLOW); + autoBribe.deposit(address(FLOW), depositAmountFLOW, depositWeeks); + vm.stopPrank(); + + uint256 balanceBeforeLR = LR.balanceOf(address(this)); + uint256 balanceBeforeFLOW = FLOW.balanceOf(address(this)); + + for (uint256 i = 0; i < depositWeeks - 1; ) { + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + unchecked { + ++i; + } + } + + assertGt(LR.balanceOf(address(autoBribe)), 0); + assertGt(FLOW.balanceOf(address(autoBribe)), 0); + + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + assertEq(LR.balanceOf(address(autoBribe)), 0); + assertEq(FLOW.balanceOf(address(autoBribe)), 0); + assertEq( + LR.balanceOf(address(wbribe)) + + LR.balanceOf(address(this)) - + balanceBeforeLR, + depositAmountLR + ); + assertEq( + FLOW.balanceOf(address(wbribe)) + + FLOW.balanceOf(address(this)) - + balanceBeforeFLOW, + depositAmountFLOW + ); + } + + function testCanDepositAllAndBribeEveryWeek(uint256 depositWeeks) public { + vm.assume(depositWeeks <= 52 && depositWeeks > 0); + vm.warp(block.timestamp + 1 weeks / 2); + + // deposit tokens + address[] memory bribeTokens = new address[](2); + bribeTokens[0] = address(LR); + bribeTokens[1] = address(FLOW); + + // Project depoit tokens + vm.startPrank(address(owner2)); + LR.approve(address(autoBribe), type(uint256).max); + FLOW.approve(address(autoBribe), type(uint256).max); + autoBribe.depositAll(bribeTokens, depositWeeks); + vm.stopPrank(); + + uint256 balanceBeforeLR = LR.balanceOf(address(this)); + uint256 balanceBeforeFLOW = FLOW.balanceOf(address(this)); + + for (uint256 i = 0; i < depositWeeks - 1; ) { + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + unchecked { + ++i; + } + } + + assertGt(LR.balanceOf(address(autoBribe)), 0); + assertGt(FLOW.balanceOf(address(autoBribe)), 0); + + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + assertEq(LR.balanceOf(address(autoBribe)), 0); + assertEq(FLOW.balanceOf(address(autoBribe)), 0); + + assertEq( + LR.balanceOf(address(wbribe)) + + LR.balanceOf(address(this)) - + balanceBeforeLR, + 1e25 + ); + assertEq( + FLOW.balanceOf(address(wbribe)) + + FLOW.balanceOf(address(this)) - + balanceBeforeFLOW, + 1e25 + ); + } + + function testRedeposit( + uint256 depositAmountLR, + uint256 depositWeeks + ) public { + vm.assume( + depositAmountLR > depositWeeks && + depositAmountLR <= 1e24 && + depositWeeks > 0 && + depositWeeks < 52 + ); + + vm.warp(block.timestamp + 1 weeks / 2); + + // Project deposit tokens + vm.startPrank(address(owner2)); + LR.approve(address(autoBribe), type(uint256).max); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + vm.stopPrank(); + + uint256 balanceBeforeLR = LR.balanceOf(address(this)); + + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + vm.startPrank(address(owner2)); + LR.approve(address(autoBribe), depositAmountLR); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + vm.stopPrank(); + + for (uint256 i = 0; i < depositWeeks * 2 - 2; ) { + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + unchecked { + ++i; + } + } + + assertGt(LR.balanceOf(address(autoBribe)), 0); + + autoBribe.bribe(); + vm.warp(block.timestamp + 1 weeks); + + assertEq(LR.balanceOf(address(autoBribe)), 0); + assertEq( + LR.balanceOf(address(wbribe)) + + LR.balanceOf(address(this)) - + balanceBeforeLR, + depositAmountLR * 2 + ); + } + + function testEmptyOut( + uint256 depositAmountLR, + uint256 depositAmountFLOW, + uint256 depositWeeks + ) public { + vm.assume( + depositAmountLR > depositWeeks && + depositAmountLR <= 1e25 && + depositAmountFLOW > depositWeeks && + depositAmountFLOW <= 1e25 && + depositWeeks > 0 && + depositWeeks < 52 + ); + + vm.warp(block.timestamp + 1 weeks / 2); + + // Project deposit tokens + vm.startPrank(address(owner2)); + LR.approve(address(autoBribe), depositAmountLR); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + + FLOW.approve(address(autoBribe), depositAmountFLOW); + autoBribe.deposit(address(FLOW), depositAmountFLOW, depositWeeks); + + autoBribe.seal(); + vm.stopPrank(); + + vm.expectRevert("only project can empty out"); + autoBribe.emptyOut(); + + vm.startPrank(address(owner2)); + vm.expectRevert("deposit is sealed"); + autoBribe.emptyOut(); + vm.stopPrank(); + + vm.startPrank(address(owner)); + autoBribe.unSeal(); + vm.stopPrank(); + + uint256 balanceBeforeLR = LR.balanceOf(address(owner2)); + uint256 balanceBeforeFLOW = FLOW.balanceOf(address(owner2)); + + vm.startPrank(address(owner2)); + autoBribe.emptyOut(); + vm.stopPrank(); + + assertEq(autoBribe.bribeTokenToWeeksLeft(address(LR)), 0); + assertEq(autoBribe.bribeTokenToWeeksLeft(address(FLOW)), 0); + + assertEq(LR.balanceOf(address(autoBribe)), 0); + assertEq(FLOW.balanceOf(address(autoBribe)), 0); + + assertEq( + LR.balanceOf(address(owner2)) - balanceBeforeLR, + depositAmountLR + ); + assertEq( + FLOW.balanceOf(address(owner2)) - balanceBeforeFLOW, + depositAmountFLOW + ); + } +} From ced74a05195091a10dcae4ba29c5c140fcefbee4 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 08:30:17 +0800 Subject: [PATCH 142/156] fix: fix merge error --- contracts/AutoBribe.sol | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index 691bf462..226d4850 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -149,17 +149,6 @@ contract AutoBribe is Ownable { emit UnSealed(block.timestamp); } - //Allows project to seal the vault making it not possible for them to withdraw their tokens - function seal() public { - require(msg.sender = project); - sealed = true; - } - - //Allows Velocimeter to re allow project to withdraw their tokens - function unSeal() public onlyOwner { - sealed = false; - } - function setProject(address _newWallet) public { require( msg.sender == project || msg.sender == owner(), From ca29a68c83c611870d6ebea12789d0742d6e6bb9 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 10:22:11 +0800 Subject: [PATCH 143/156] fix: fix AutoBribe --- contracts/AutoBribe.sol | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index 226d4850..1dc6845d 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -20,6 +20,7 @@ contract AutoBribe is Ownable { address public project; bool public depositSealed; + bool public initialized; uint256 public nextWeek; address[] public bribeTokens; mapping(address => bool) public bribeTokensDeposited; @@ -91,7 +92,7 @@ contract AutoBribe is Ownable { _bribeToken = bribeTokens[i]; uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; uint256 bribeAmount = balance(_bribeToken) / weeksLeft; - uint256 gasReward = bribeAmount / 10000; + uint256 gasReward = bribeAmount / 200; _safeTransfer(_bribeToken, msg.sender, gasReward); WrappedBribe(wBribe).notifyRewardAmount( _bribeToken, @@ -151,9 +152,12 @@ contract AutoBribe is Ownable { function setProject(address _newWallet) public { require( - msg.sender == project || msg.sender == owner(), + msg.sender == project || (msg.sender == owner() && !initialized), "only project or team" ); + if (!initialized) { + initialized = true; + } project = _newWallet; } From e16a71c7c0ff2d55d9c098812bea4a09b720c2c9 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 10:27:41 +0800 Subject: [PATCH 144/156] fix: add tests for setProject --- contracts/AutoBribe.sol | 2 +- test/AutoBribe.t.sol | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index 1dc6845d..a690a986 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -153,7 +153,7 @@ contract AutoBribe is Ownable { function setProject(address _newWallet) public { require( msg.sender == project || (msg.sender == owner() && !initialized), - "only project or team" + "only project / team can only set once" ); if (!initialized) { initialized = true; diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index ce8e3d2c..d009807b 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -313,4 +313,21 @@ contract AutoBribeTest is BaseTest { depositAmountFLOW ); } + + function testTeamCannotSetProjectTwice() public { + vm.startPrank(address(owner)); + vm.expectRevert("only project / team can only set once"); + autoBribe.setProject(address(owner2)); + vm.stopPrank(); + } + + function testProjectSetProjectTwice() public { + vm.startPrank(address(owner2)); + autoBribe.setProject(address(owner3)); + vm.stopPrank(); + + vm.startPrank(address(owner3)); + autoBribe.setProject(address(0x10)); + vm.stopPrank(); + } } From ebc8d31f5aa19b8ab334ed69c8e3f102076fd81f Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 11:48:14 +0800 Subject: [PATCH 145/156] feat: add last updated in wrapped bribe --- contracts/WrappedBribe.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/WrappedBribe.sol b/contracts/WrappedBribe.sol index bc9ce2a0..25ab054f 100644 --- a/contracts/WrappedBribe.sol +++ b/contracts/WrappedBribe.sol @@ -19,6 +19,7 @@ contract WrappedBribe { mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch; mapping(address => uint) public periodFinish; + mapping(address => uint) public lastUpdated; mapping(address => mapping(uint => uint)) public lastEarn; address[] public rewards; @@ -204,6 +205,7 @@ contract WrappedBribe { tokenRewardBalance[tokens[i]] = rewardBalance + difference; periodFinish[tokens[i]] = adjustedTstamp + DURATION; + lastUpdated[tokens[i]] = block.timetstamp; emit NotifyReward(msg.sender, tokens[i], adjustedTstamp, difference); } From 62317d59bc3c37fcee80617d8d3a9e5ede720bad Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 11:49:28 +0800 Subject: [PATCH 146/156] fix: fix typo --- contracts/WrappedBribe.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/WrappedBribe.sol b/contracts/WrappedBribe.sol index 25ab054f..6fb0a219 100644 --- a/contracts/WrappedBribe.sol +++ b/contracts/WrappedBribe.sol @@ -205,7 +205,7 @@ contract WrappedBribe { tokenRewardBalance[tokens[i]] = rewardBalance + difference; periodFinish[tokens[i]] = adjustedTstamp + DURATION; - lastUpdated[tokens[i]] = block.timetstamp; + lastUpdated[tokens[i]] = block.timestamp; emit NotifyReward(msg.sender, tokens[i], adjustedTstamp, difference); } From 1cc549ab3081bb7032643c99983566f387397fdb Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 12:15:11 +0800 Subject: [PATCH 147/156] fix: remove createAutoBribe --- contracts/factories/WrappedBribeFactory.sol | 16 ---------------- test/AutoBribe.t.sol | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/contracts/factories/WrappedBribeFactory.sol b/contracts/factories/WrappedBribeFactory.sol index 821d0c96..d32dff75 100644 --- a/contracts/factories/WrappedBribeFactory.sol +++ b/contracts/factories/WrappedBribeFactory.sol @@ -1,14 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import {AutoBribe} from 'contracts/AutoBribe.sol'; import {WrappedBribe} from 'contracts/WrappedBribe.sol'; contract WrappedBribeFactory { address public immutable team; address public voter; mapping(address => address) public oldBribeToNew; - mapping(address => address) public oldBribeToAutoBribe; address public last_bribe; event VoterSet(address indexed setter, address indexed voter); @@ -27,20 +25,6 @@ contract WrappedBribeFactory { return last_bribe; } - function createAutoBribe(address existing_bribe) external returns (address auto_bribe) { - address wBribe = oldBribeToNew[existing_bribe]; - require( - wBribe != address(0), - "Wrapped bribe not yet created" - ); - require( - oldBribeToAutoBribe[existing_bribe] == address(0), - "Auto bribe already created" - ); - auto_bribe = address(new AutoBribe(wBribe, team)); - oldBribeToAutoBribe[existing_bribe] = auto_bribe; - } - function setVoter(address _voter) external { require(voter == address(0), "Already initialized"); voter = _voter; diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index d009807b..e5b18c94 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -77,7 +77,7 @@ contract AutoBribeTest is BaseTest { gauge = Gauge(voter.createGauge(address(pair))); xbribe = ExternalBribe(gauge.external_bribe()); wbribe = WrappedBribe(wbribeFactory.oldBribeToNew(address(xbribe))); - autoBribe = AutoBribe(wbribeFactory.createAutoBribe(address(xbribe))); + autoBribe = new AutoBribe(address(wbribe), address(owner)); vm.startPrank(address(owner)); autoBribe.setProject(address(owner2)); From 8f33aedf62b9d9bb84753660340fe6ab7044a4e8 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 15:58:17 +0800 Subject: [PATCH 148/156] feat: add AutoBribeFactory --- contracts/factories/AutoBribeFactory.sol | 27 ++++++++++++++++++++++++ test/AutoBribe.t.sol | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 contracts/factories/AutoBribeFactory.sol diff --git a/contracts/factories/AutoBribeFactory.sol b/contracts/factories/AutoBribeFactory.sol new file mode 100644 index 00000000..279a951a --- /dev/null +++ b/contracts/factories/AutoBribeFactory.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import {AutoBribe} from "contracts/AutoBribe.sol"; +import 'contracts/interfaces/ITurnstile.sol'; + +contract AutoBribeFactory { + address public constant TURNSTILE = + 0xEcf044C5B4b867CFda001101c617eCd347095B44; + uint256 public immutable csrNftId; + address public immutable team; + address public immutable wBribeFactory; + + constructor(address _team, address _wBribeFactory, uint256 _csrNftId) { + team = _team; + wBribeFactory = _wBribeFactory; + ITurnstile(TURNSTILE).assign(_csrNftId); + csrNftId = _csrNftId; + } + + function createAutoBribe( + address wbribe + ) external returns (address auto_bribe) { + require(wbribe != address(0), "Wrapped bribe not yet created"); + auto_bribe = address(new AutoBribe(wbribe, team, csrNftId)); + } +} diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index e5b18c94..f9debb0b 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -77,7 +77,7 @@ contract AutoBribeTest is BaseTest { gauge = Gauge(voter.createGauge(address(pair))); xbribe = ExternalBribe(gauge.external_bribe()); wbribe = WrappedBribe(wbribeFactory.oldBribeToNew(address(xbribe))); - autoBribe = new AutoBribe(address(wbribe), address(owner)); + autoBribe = new AutoBribe(address(wbribe), address(owner), csrNftId); vm.startPrank(address(owner)); autoBribe.setProject(address(owner2)); From a49b16690d39379b534a903b98629a1caa62c1c9 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 15:57:38 +0800 Subject: [PATCH 149/156] fix: remove team in constructor of WrappedBribeFactory --- contracts/factories/WrappedBribeFactory.sol | 17 ++++------------- test/WrappedBribes.t.sol | 13 ++++++++----- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/contracts/factories/WrappedBribeFactory.sol b/contracts/factories/WrappedBribeFactory.sol index d32dff75..272049ad 100644 --- a/contracts/factories/WrappedBribeFactory.sol +++ b/contracts/factories/WrappedBribeFactory.sol @@ -1,18 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import {WrappedBribe} from 'contracts/WrappedBribe.sol'; +import {WrappedBribe} from "contracts/WrappedBribe.sol"; contract WrappedBribeFactory { - address public immutable team; - address public voter; + address public immutable voter; mapping(address => address) public oldBribeToNew; address public last_bribe; - event VoterSet(address indexed setter, address indexed voter); - - constructor(address _team) { - team = _team; + constructor(address _voter) { + voter = _voter; } function createBribe(address existing_bribe) external returns (address) { @@ -24,10 +21,4 @@ contract WrappedBribeFactory { oldBribeToNew[existing_bribe] = last_bribe; return last_bribe; } - - function setVoter(address _voter) external { - require(voter == address(0), "Already initialized"); - voter = _voter; - emit VoterSet(msg.sender, _voter); - } } diff --git a/test/WrappedBribes.t.sol b/test/WrappedBribes.t.sol index c0490420..c6eb0b84 100644 --- a/test/WrappedBribes.t.sol +++ b/test/WrappedBribes.t.sol @@ -3,13 +3,15 @@ pragma solidity 0.8.13; import './BaseTest.sol'; import "contracts/WrappedBribe.sol"; import "contracts/factories/WrappedBribeFactory.sol"; +import "contracts/factories/WrappedExternalBribeFactory.sol"; import "forge-std/console2.sol"; contract WrappedBribesTest is BaseTest { VotingEscrow escrow; GaugeFactory gaugeFactory; BribeFactory bribeFactory; - WrappedBribeFactory wxbribeFactory; + WrappedExternalBribeFactory wxbribeFactory; + WrappedBribeFactory wbribeFacotry; Voter voter; RewardsDistributor distributor; Minter minter; @@ -39,12 +41,13 @@ contract WrappedBribesTest is BaseTest { // deployVoter() gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - wxbribeFactory = new WrappedBribeFactory(address(owner)); + wxbribeFactory = new WrappedExternalBribeFactory(); voter = new Voter(address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), address(wxbribeFactory)); + wbribeFacotry = new WrappedBribeFactory(address(voter)); escrow.setVoter(address(voter)); - wxbribeFactory.setVoter(address(voter)); factory.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); deployPairWithOwner(address(owner)); // deployMinter() @@ -67,13 +70,13 @@ contract WrappedBribesTest is BaseTest { // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); xbribe = ExternalBribe(gauge.external_bribe()); - wxbribe = WrappedBribe(wxbribeFactory.oldBribeToNew(address(xbribe))); + wxbribe = WrappedBribe(wbribeFacotry.createBribe(address(xbribe))); // USDC - FRAX stable gauge2 = Gauge(voter.createGauge(address(pair2))); xbribe2 = ExternalBribe(gauge2.external_bribe()); - wxbribe2 = WrappedBribe(wxbribeFactory.oldBribeToNew(address(xbribe2))); + wxbribe2 = WrappedBribe(wbribeFacotry.createBribe(address(xbribe2))); // ve FLOW.approve(address(escrow), TOKEN_1); From 202aa3779e024f5607d959dfab82cfb27c51ee9b Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Fri, 28 Apr 2023 17:53:50 +0800 Subject: [PATCH 150/156] fix: fix test cases --- contracts/factories/AutoBribeFactory.sol | 10 ++-------- test/AutoBribe.t.sol | 13 ++++++++----- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/contracts/factories/AutoBribeFactory.sol b/contracts/factories/AutoBribeFactory.sol index 279a951a..53363379 100644 --- a/contracts/factories/AutoBribeFactory.sol +++ b/contracts/factories/AutoBribeFactory.sol @@ -2,26 +2,20 @@ pragma solidity 0.8.13; import {AutoBribe} from "contracts/AutoBribe.sol"; -import 'contracts/interfaces/ITurnstile.sol'; contract AutoBribeFactory { - address public constant TURNSTILE = - 0xEcf044C5B4b867CFda001101c617eCd347095B44; - uint256 public immutable csrNftId; address public immutable team; address public immutable wBribeFactory; - constructor(address _team, address _wBribeFactory, uint256 _csrNftId) { + constructor(address _team, address _wBribeFactory) { team = _team; wBribeFactory = _wBribeFactory; - ITurnstile(TURNSTILE).assign(_csrNftId); - csrNftId = _csrNftId; } function createAutoBribe( address wbribe ) external returns (address auto_bribe) { require(wbribe != address(0), "Wrapped bribe not yet created"); - auto_bribe = address(new AutoBribe(wbribe, team, csrNftId)); + auto_bribe = address(new AutoBribe(wbribe, team)); } } diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index f9debb0b..1a0cefd4 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -4,6 +4,7 @@ import "./BaseTest.sol"; import "contracts/AutoBribe.sol"; import "contracts/WrappedBribe.sol"; import "contracts/factories/WrappedBribeFactory.sol"; +import "contracts/factories/WrappedExternalBribeFactory.sol"; import "forge-std/console2.sol"; contract AutoBribeTest is BaseTest { @@ -11,6 +12,7 @@ contract AutoBribeTest is BaseTest { GaugeFactory gaugeFactory; BribeFactory bribeFactory; WrappedBribeFactory wbribeFactory; + WrappedExternalBribeFactory wxbribeFactory; Voter voter; RewardsDistributor distributor; Minter minter; @@ -42,18 +44,19 @@ contract AutoBribeTest is BaseTest { // deployVoter() gaugeFactory = new GaugeFactory(); bribeFactory = new BribeFactory(); - wbribeFactory = new WrappedBribeFactory(address(owner)); + wxbribeFactory = new WrappedExternalBribeFactory(); voter = new Voter( address(escrow), address(factory), address(gaugeFactory), address(bribeFactory), - address(wbribeFactory) + address(wxbribeFactory) ); + wbribeFactory = new WrappedBribeFactory(address(voter)); escrow.setVoter(address(voter)); - wbribeFactory.setVoter(address(voter)); factory.setVoter(address(voter)); + wxbribeFactory.setVoter(address(voter)); deployPairWithOwner(address(owner)); // deployMinter() @@ -76,8 +79,8 @@ contract AutoBribeTest is BaseTest { // USDC - FRAX stable gauge = Gauge(voter.createGauge(address(pair))); xbribe = ExternalBribe(gauge.external_bribe()); - wbribe = WrappedBribe(wbribeFactory.oldBribeToNew(address(xbribe))); - autoBribe = new AutoBribe(address(wbribe), address(owner), csrNftId); + wbribe = WrappedBribe(wbribeFactory.createBribe(address(xbribe))); + autoBribe = new AutoBribe(address(wbribe), address(owner)); vm.startPrank(address(owner)); autoBribe.setProject(address(owner2)); From a969b070080b6b84d585b5a4824a6fa328d5ca89 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Sun, 30 Apr 2023 00:09:58 +0800 Subject: [PATCH 151/156] fix: move math from bribe to deposit --- contracts/AutoBribe.sol | 61 ++++++++++++++++++++++++------------ test/AutoBribe.t.sol | 68 +++++++++++++++++++++++++++-------------- 2 files changed, 86 insertions(+), 43 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index a690a986..cd0d4434 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -24,7 +24,8 @@ contract AutoBribe is Ownable { uint256 public nextWeek; address[] public bribeTokens; mapping(address => bool) public bribeTokensDeposited; - mapping(address => uint256) public bribeTokenToWeeksLeft; + mapping(address => uint256) public bribeTokenToAmountEachWeek; + mapping(address => uint256) public bribeTokenToGasRewardEachWeek; event Deposited( address indexed _bribeToken, @@ -52,7 +53,7 @@ contract AutoBribe is Ownable { address bribeToken = _bribeTokens[i]; deposit( bribeToken, - IERC20(bribeToken).balanceOf(msg.sender), + IERC20(bribeToken).balanceOf(msg.sender) / _weeks, _weeks ); unchecked { @@ -63,42 +64,61 @@ contract AutoBribe is Ownable { function deposit( address _bribeToken, - uint256 _amount, + uint256 _amountPerWeek, uint256 _weeks ) public { require(msg.sender == project, "only the project can bribe"); - require(_amount > 0, "Why are you depositing 0 tokens?"); + require(_amountPerWeek > 0, "Why are you depositing 0 tokens?"); require(_weeks > 0, "You have to put at least 1 week"); - _safeTransferFrom(_bribeToken, msg.sender, address(this), _amount); + _safeTransferFrom( + _bribeToken, + msg.sender, + address(this), + _amountPerWeek * _weeks + ); uint256 allowance = IERC20(_bribeToken).allowance( address(this), wBribe ); - _safeApprove(_bribeToken, wBribe, allowance + _amount); + _safeApprove(_bribeToken, wBribe, allowance + _amountPerWeek * _weeks); if (!bribeTokensDeposited[_bribeToken]) { bribeTokensDeposited[_bribeToken] = true; bribeTokens.push(_bribeToken); } - bribeTokenToWeeksLeft[_bribeToken] += _weeks; + uint256 gasRewardPerWeek = _amountPerWeek / 200; + bribeTokenToGasRewardEachWeek[_bribeToken] += gasRewardPerWeek; - emit Deposited(_bribeToken, _amount, _weeks); + uint256 amountEachWeek = _amountPerWeek - gasRewardPerWeek; + bribeTokenToAmountEachWeek[_bribeToken] += amountEachWeek; + + emit Deposited(_bribeToken, _amountPerWeek * _weeks, _weeks); } function bribe() public { uint256 length = bribeTokens.length; + uint256 gasRewardPerWeek; + uint256 bribeAmountPerWeek; + uint256 tokenBalance; address _bribeToken; for (uint256 i = 0; i < length; ) { if (block.timestamp >= nextWeek) { _bribeToken = bribeTokens[i]; - uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; - uint256 bribeAmount = balance(_bribeToken) / weeksLeft; - uint256 gasReward = bribeAmount / 200; - _safeTransfer(_bribeToken, msg.sender, gasReward); - WrappedBribe(wBribe).notifyRewardAmount( - _bribeToken, - bribeAmount - gasReward - ); - bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; + gasRewardPerWeek = bribeTokenToGasRewardEachWeek[_bribeToken]; + bribeAmountPerWeek = bribeTokenToAmountEachWeek[_bribeToken]; + tokenBalance = balance(_bribeToken); + if (tokenBalance >= gasRewardPerWeek + bribeAmountPerWeek) { + _safeTransfer(_bribeToken, msg.sender, gasRewardPerWeek); + WrappedBribe(wBribe).notifyRewardAmount( + _bribeToken, + bribeAmountPerWeek + ); + } else if (tokenBalance > gasRewardPerWeek) { + _safeTransfer(_bribeToken, msg.sender, gasRewardPerWeek); + WrappedBribe(wBribe).notifyRewardAmount( + _bribeToken, + tokenBalance - gasRewardPerWeek + ); + } } unchecked { ++i; @@ -120,11 +140,12 @@ contract AutoBribe is Ownable { require(!depositSealed, "deposit is sealed"); uint256 length = bribeTokens.length; uint256 amount; - + address bribeToken; for (uint256 i = 0; i < length; ) { - address bribeToken = bribeTokens[i]; + bribeToken = bribeTokens[i]; amount = balance(bribeToken); - bribeTokenToWeeksLeft[bribeToken] = 0; + bribeTokenToGasRewardEachWeek[bribeToken] = 0; + bribeTokenToAmountEachWeek[bribeToken] = 0; _safeTransfer(bribeToken, msg.sender, amount); unchecked { diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index 1a0cefd4..84bc4dd7 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -94,10 +94,15 @@ contract AutoBribeTest is BaseTest { } function testCanDepositAndBribeEveryWeek( - uint256 depositAmountLR, - uint256 depositAmountFLOW, - uint256 depositWeeks + uint128 depositAmountPerWeekLR, + uint128 depositAmountPerWeekFLOW, + uint128 depositWeeks ) public { + uint256 depositAmountLR = uint256(depositAmountPerWeekLR) * + uint256(depositWeeks); + uint256 depositAmountFLOW = uint256(depositAmountPerWeekFLOW) * + uint256(depositWeeks); + vm.assume( depositAmountLR > depositWeeks && depositAmountLR <= 1e25 && @@ -112,10 +117,13 @@ contract AutoBribeTest is BaseTest { // Project deposit tokens vm.startPrank(address(owner2)); LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); - + autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); FLOW.approve(address(autoBribe), depositAmountFLOW); - autoBribe.deposit(address(FLOW), depositAmountFLOW, depositWeeks); + autoBribe.deposit( + address(FLOW), + depositAmountPerWeekFLOW, + depositWeeks + ); vm.stopPrank(); uint256 balanceBeforeLR = LR.balanceOf(address(this)); @@ -193,20 +201,22 @@ contract AutoBribeTest is BaseTest { LR.balanceOf(address(wbribe)) + LR.balanceOf(address(this)) - balanceBeforeLR, - 1e25 + (1e25 / depositWeeks) * depositWeeks ); assertEq( FLOW.balanceOf(address(wbribe)) + FLOW.balanceOf(address(this)) - balanceBeforeFLOW, - 1e25 + (1e25 / depositWeeks) * depositWeeks ); } function testRedeposit( - uint256 depositAmountLR, - uint256 depositWeeks + uint128 depositAmountPerWeekLR, + uint128 depositWeeks ) public { + uint256 depositAmountLR = uint256(depositAmountPerWeekLR) * + uint256(depositWeeks); vm.assume( depositAmountLR > depositWeeks && depositAmountLR <= 1e24 && @@ -218,8 +228,8 @@ contract AutoBribeTest is BaseTest { // Project deposit tokens vm.startPrank(address(owner2)); - LR.approve(address(autoBribe), type(uint256).max); - autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + LR.approve(address(autoBribe), depositAmountLR); + autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); vm.stopPrank(); uint256 balanceBeforeLR = LR.balanceOf(address(this)); @@ -229,7 +239,7 @@ contract AutoBribeTest is BaseTest { vm.startPrank(address(owner2)); LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); vm.stopPrank(); for (uint256 i = 0; i < depositWeeks * 2 - 2; ) { @@ -241,7 +251,7 @@ contract AutoBribeTest is BaseTest { } } - assertGt(LR.balanceOf(address(autoBribe)), 0); + assertGe(LR.balanceOf(address(autoBribe)), 0); autoBribe.bribe(); vm.warp(block.timestamp + 1 weeks); @@ -256,14 +266,19 @@ contract AutoBribeTest is BaseTest { } function testEmptyOut( - uint256 depositAmountLR, - uint256 depositAmountFLOW, - uint256 depositWeeks + uint128 depositAmountPerWeekLR, + uint128 depositAmountPerWeekFLOW, + uint128 depositWeeks ) public { + uint256 depositAmountLR = uint256(depositAmountPerWeekLR) * + uint256(depositWeeks); + uint256 depositAmountFLOW = uint256(depositAmountPerWeekFLOW) * + uint256(depositWeeks); + vm.assume( - depositAmountLR > depositWeeks && + depositAmountLR > uint256(depositWeeks) && depositAmountLR <= 1e25 && - depositAmountFLOW > depositWeeks && + depositAmountFLOW > uint256(depositWeeks) && depositAmountFLOW <= 1e25 && depositWeeks > 0 && depositWeeks < 52 @@ -274,10 +289,14 @@ contract AutoBribeTest is BaseTest { // Project deposit tokens vm.startPrank(address(owner2)); LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); FLOW.approve(address(autoBribe), depositAmountFLOW); - autoBribe.deposit(address(FLOW), depositAmountFLOW, depositWeeks); + autoBribe.deposit( + address(FLOW), + depositAmountPerWeekFLOW, + depositWeeks + ); autoBribe.seal(); vm.stopPrank(); @@ -301,8 +320,11 @@ contract AutoBribeTest is BaseTest { autoBribe.emptyOut(); vm.stopPrank(); - assertEq(autoBribe.bribeTokenToWeeksLeft(address(LR)), 0); - assertEq(autoBribe.bribeTokenToWeeksLeft(address(FLOW)), 0); + assertEq(autoBribe.bribeTokenToGasRewardEachWeek(address(LR)), 0); + assertEq(autoBribe.bribeTokenToGasRewardEachWeek(address(FLOW)), 0); + + assertEq(autoBribe.bribeTokenToAmountEachWeek(address(LR)), 0); + assertEq(autoBribe.bribeTokenToAmountEachWeek(address(FLOW)), 0); assertEq(LR.balanceOf(address(autoBribe)), 0); assertEq(FLOW.balanceOf(address(autoBribe)), 0); From 18602b74007bda19a4b6f6513d72d5a60c472c1b Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 2 May 2023 11:25:57 +0800 Subject: [PATCH 152/156] fix: set nextWeek to block.timestamp in constructor --- contracts/AutoBribe.sol | 1 + test/AutoBribe.t.sol | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index a690a986..93a71867 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -38,6 +38,7 @@ contract AutoBribe is Ownable { constructor(address _wBribe, address _team) { wBribe = _wBribe; + nextWeek = block.timestamp; _transferOwnership(_team); } diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index 1a0cefd4..3cb1327d 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -255,6 +255,39 @@ contract AutoBribeTest is BaseTest { ); } + function testCannotBribeTwice( + uint256 depositAmountLR, + uint256 depositWeeks + ) public { + vm.assume( + depositAmountLR > depositWeeks && + depositAmountLR <= 1e25 && + depositWeeks > 0 && + depositWeeks < 52 + ); + + vm.warp(block.timestamp + 1 weeks / 2); + + // Project deposit tokens + vm.startPrank(address(owner2)); + LR.approve(address(autoBribe), depositAmountLR); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + vm.stopPrank(); + + uint256 pre = LR.balanceOf(address(wbribe)); + + autoBribe.bribe(); + + uint256 post = LR.balanceOf(address(wbribe)); + + autoBribe.bribe(); + + uint256 post_post = LR.balanceOf(address(wbribe)); + + assertGt(post - pre, 0); + assertEq(post_post - post, 0); + } + function testEmptyOut( uint256 depositAmountLR, uint256 depositAmountFLOW, From 9876ef37a8f6f9506264c189ece7e5a098eb0775 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 2 May 2023 11:55:32 +0800 Subject: [PATCH 153/156] fix: add checking to avoid re-bribing in the same week --- contracts/AutoBribe.sol | 27 ++++++++++++--------------- test/AutoBribe.t.sol | 10 +--------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index 93a71867..ce5cdce6 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -86,29 +86,26 @@ contract AutoBribe is Ownable { } function bribe() public { + require(block.timestamp >= nextWeek, "already bribed this week"); uint256 length = bribeTokens.length; address _bribeToken; for (uint256 i = 0; i < length; ) { - if (block.timestamp >= nextWeek) { - _bribeToken = bribeTokens[i]; - uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; - uint256 bribeAmount = balance(_bribeToken) / weeksLeft; - uint256 gasReward = bribeAmount / 200; - _safeTransfer(_bribeToken, msg.sender, gasReward); - WrappedBribe(wBribe).notifyRewardAmount( - _bribeToken, - bribeAmount - gasReward - ); - bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; - } + _bribeToken = bribeTokens[i]; + uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; + uint256 bribeAmount = balance(_bribeToken) / weeksLeft; + uint256 gasReward = bribeAmount / 200; + _safeTransfer(_bribeToken, msg.sender, gasReward); + WrappedBribe(wBribe).notifyRewardAmount( + _bribeToken, + bribeAmount - gasReward + ); + bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; unchecked { ++i; } } - - emit Bribed(nextWeek, msg.sender); - nextWeek = nextWeek + 604800; + emit Bribed(nextWeek, msg.sender); } function balance(address _bribeToken) public view returns (uint) { diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index 3cb1327d..d1b1b194 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -274,18 +274,10 @@ contract AutoBribeTest is BaseTest { autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); vm.stopPrank(); - uint256 pre = LR.balanceOf(address(wbribe)); - autoBribe.bribe(); - uint256 post = LR.balanceOf(address(wbribe)); - + vm.expectRevert("already bribed this week"); autoBribe.bribe(); - - uint256 post_post = LR.balanceOf(address(wbribe)); - - assertGt(post - pre, 0); - assertEq(post_post - post, 0); } function testEmptyOut( From 872a64f669887517d3c917b7ba0fcddccdc41f6b Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Wed, 3 May 2023 15:57:40 +0800 Subject: [PATCH 154/156] fix: amend AutoBribe --- contracts/AutoBribe.sol | 115 +++++++++++++++++++++++----------------- test/AutoBribe.t.sol | 8 +-- 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index ce5cdce6..a8adbc66 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -1,12 +1,10 @@ // SPDX-License-Identifier: MIT import "openzeppelin-contracts/contracts/access/Ownable.sol"; -import "openzeppelin-contracts/contracts/utils/Context.sol"; -import "openzeppelin-contracts/contracts/utils/Address.sol"; import "contracts/interfaces/IERC20.sol"; import "contracts/WrappedBribe.sol"; -pragma solidity 0.8.13; +pragma solidity ^0.8.13; // the purpose of this contract is to allow the projects to deposit bribes that will bribe their pools for a period of time // they will need to set up a public keeper, anyone can send the bribes @@ -25,6 +23,7 @@ contract AutoBribe is Ownable { address[] public bribeTokens; mapping(address => bool) public bribeTokensDeposited; mapping(address => uint256) public bribeTokenToWeeksLeft; + string public bribeName; event Deposited( address indexed _bribeToken, @@ -36,32 +35,53 @@ contract AutoBribe is Ownable { event Sealed(uint256 indexed _timestamp); event UnSealed(uint256 indexed _timestamp); - constructor(address _wBribe, address _team) { + constructor(address _wBribe, address _team, string _name) { wBribe = _wBribe; nextWeek = block.timestamp; _transferOwnership(_team); + bribeName = _name; } - //####USER FUNCTIONS##### + //######################################## + //###########PUBLIC FUNCTIONS############# + //######################################## - function depositAll( - address[] memory _bribeTokens, - uint256 _weeks - ) external { - uint256 length = _bribeTokens.length; + //This public function allows anyone to send the weekly allocation to the bribe contract + //There is a small reward for calling this function + //It can only be called once a week + function bribe() public { + require(block.timestamp >= nextWeek, "already bribed this week"); + uint256 length = bribeTokens.length; + address _bribeToken; for (uint256 i = 0; i < length; ) { - address bribeToken = _bribeTokens[i]; - deposit( - bribeToken, - IERC20(bribeToken).balanceOf(msg.sender), - _weeks + _bribeToken = bribeTokens[i]; + uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; + uint256 bribeAmount = balance(_bribeToken) / weeksLeft; + uint256 gasReward = bribeAmount / 200; + _safeTransfer(_bribeToken, msg.sender, gasReward); + WrappedBribe(wBribe).notifyRewardAmount( + _bribeToken, + bribeAmount - gasReward ); + bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; unchecked { ++i; } } + nextWeek = nextWeek + 604800; + emit Bribed(nextWeek, msg.sender); } + //This just returns the balance of bribe tokens in the contract + function balance(address _bribeToken) public view returns (uint) { + return IERC20(_bribeToken).balanceOf(address(this)); + } + + //######################################## + //########PROJECT ADMIN FUNCTIONS######### + //######################################## + + //Allows project to deposit bribe tokens and set the weeks of which they are divided up into function deposit( address _bribeToken, uint256 _amount, @@ -85,34 +105,7 @@ contract AutoBribe is Ownable { emit Deposited(_bribeToken, _amount, _weeks); } - function bribe() public { - require(block.timestamp >= nextWeek, "already bribed this week"); - uint256 length = bribeTokens.length; - address _bribeToken; - for (uint256 i = 0; i < length; ) { - _bribeToken = bribeTokens[i]; - uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; - uint256 bribeAmount = balance(_bribeToken) / weeksLeft; - uint256 gasReward = bribeAmount / 200; - _safeTransfer(_bribeToken, msg.sender, gasReward); - WrappedBribe(wBribe).notifyRewardAmount( - _bribeToken, - bribeAmount - gasReward - ); - bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; - unchecked { - ++i; - } - } - nextWeek = nextWeek + 604800; - emit Bribed(nextWeek, msg.sender); - } - - function balance(address _bribeToken) public view returns (uint) { - return IERC20(_bribeToken).balanceOf(address(this)); - } - - //####Admin Functions##### + //Allows the project to retrieve their bribe tokens function emptyOut() public { require(msg.sender == project, "only project can empty out"); require(!depositSealed, "deposit is sealed"); @@ -141,6 +134,16 @@ contract AutoBribe is Ownable { emit Sealed(block.timestamp); } + //Allows project to change their controlling wallet + function setProject(address _newWallet) public { + require(msg.sender == project); + project = _newWallet; + } + + //######################################## + //#######VELOCIMETER ADMIN FUNCTIONS###### + //######################################## + //Allows Velocimeter to re allow project to withdraw their tokens function unSeal() public onlyOwner { depositSealed = false; @@ -148,11 +151,8 @@ contract AutoBribe is Ownable { emit UnSealed(block.timestamp); } - function setProject(address _newWallet) public { - require( - msg.sender == project || (msg.sender == owner() && !initialized), - "only project / team can only set once" - ); + function initProject(address _newWallet) public onlyOwner { + require(!initialized, "project wallet can only be set once by team"); if (!initialized) { initialized = true; } @@ -165,6 +165,25 @@ contract AutoBribe is Ownable { _safeTransfer(_token, msg.sender, amount); } + //######################################## + //############RECLOCK FUNCTION############ + //######################################## + + // Allows project or Velocimeter to reset the week to the current block + // This should only be called with consideration as it can allow for double bribes in a single week. + // Best use is to call it BEFORE, bribe() is called in a given week + function reclockBribeToNow() external { + require( + msg.sender == project || msg.sender == owner(), + "you can't call this" + ); + nextWeek = block.timestamp; + } + + //######################################## + //############INTERNAL FUNCTIONS########## + //######################################## + function _safeTransfer(address token, address to, uint256 value) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call( diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index d1b1b194..44d60cac 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -83,7 +83,7 @@ contract AutoBribeTest is BaseTest { autoBribe = new AutoBribe(address(wbribe), address(owner)); vm.startPrank(address(owner)); - autoBribe.setProject(address(owner2)); + autoBribe.initProject(address(owner2)); vm.stopPrank(); } @@ -342,10 +342,10 @@ contract AutoBribeTest is BaseTest { ); } - function testTeamCannotSetProjectTwice() public { + function testTeamCannotInitProjectTwice() public { vm.startPrank(address(owner)); - vm.expectRevert("only project / team can only set once"); - autoBribe.setProject(address(owner2)); + vm.expectRevert("project wallet can only be set once by team"); + autoBribe.initProject(address(owner2)); vm.stopPrank(); } From d984cb02972628a716f7dfab24147acd288ba013 Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Wed, 3 May 2023 16:36:26 +0800 Subject: [PATCH 155/156] fix: fix data location --- contracts/AutoBribe.sol | 2 +- contracts/factories/AutoBribeFactory.sol | 5 ++- test/AutoBribe.t.sol | 53 +----------------------- 3 files changed, 5 insertions(+), 55 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index a8adbc66..eeac5fe9 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -35,7 +35,7 @@ contract AutoBribe is Ownable { event Sealed(uint256 indexed _timestamp); event UnSealed(uint256 indexed _timestamp); - constructor(address _wBribe, address _team, string _name) { + constructor(address _wBribe, address _team, string memory _name) { wBribe = _wBribe; nextWeek = block.timestamp; _transferOwnership(_team); diff --git a/contracts/factories/AutoBribeFactory.sol b/contracts/factories/AutoBribeFactory.sol index 53363379..679bcd3c 100644 --- a/contracts/factories/AutoBribeFactory.sol +++ b/contracts/factories/AutoBribeFactory.sol @@ -13,9 +13,10 @@ contract AutoBribeFactory { } function createAutoBribe( - address wbribe + address wbribe, + string memory name ) external returns (address auto_bribe) { require(wbribe != address(0), "Wrapped bribe not yet created"); - auto_bribe = address(new AutoBribe(wbribe, team)); + auto_bribe = address(new AutoBribe(wbribe, team, name)); } } diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index 44d60cac..fe0b933e 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -80,7 +80,7 @@ contract AutoBribeTest is BaseTest { gauge = Gauge(voter.createGauge(address(pair))); xbribe = ExternalBribe(gauge.external_bribe()); wbribe = WrappedBribe(wbribeFactory.createBribe(address(xbribe))); - autoBribe = new AutoBribe(address(wbribe), address(owner)); + autoBribe = new AutoBribe(address(wbribe), address(owner), "AUTO"); vm.startPrank(address(owner)); autoBribe.initProject(address(owner2)); @@ -152,57 +152,6 @@ contract AutoBribeTest is BaseTest { ); } - function testCanDepositAllAndBribeEveryWeek(uint256 depositWeeks) public { - vm.assume(depositWeeks <= 52 && depositWeeks > 0); - vm.warp(block.timestamp + 1 weeks / 2); - - // deposit tokens - address[] memory bribeTokens = new address[](2); - bribeTokens[0] = address(LR); - bribeTokens[1] = address(FLOW); - - // Project depoit tokens - vm.startPrank(address(owner2)); - LR.approve(address(autoBribe), type(uint256).max); - FLOW.approve(address(autoBribe), type(uint256).max); - autoBribe.depositAll(bribeTokens, depositWeeks); - vm.stopPrank(); - - uint256 balanceBeforeLR = LR.balanceOf(address(this)); - uint256 balanceBeforeFLOW = FLOW.balanceOf(address(this)); - - for (uint256 i = 0; i < depositWeeks - 1; ) { - autoBribe.bribe(); - vm.warp(block.timestamp + 1 weeks); - - unchecked { - ++i; - } - } - - assertGt(LR.balanceOf(address(autoBribe)), 0); - assertGt(FLOW.balanceOf(address(autoBribe)), 0); - - autoBribe.bribe(); - vm.warp(block.timestamp + 1 weeks); - - assertEq(LR.balanceOf(address(autoBribe)), 0); - assertEq(FLOW.balanceOf(address(autoBribe)), 0); - - assertEq( - LR.balanceOf(address(wbribe)) + - LR.balanceOf(address(this)) - - balanceBeforeLR, - 1e25 - ); - assertEq( - FLOW.balanceOf(address(wbribe)) + - FLOW.balanceOf(address(this)) - - balanceBeforeFLOW, - 1e25 - ); - } - function testRedeposit( uint256 depositAmountLR, uint256 depositWeeks From f503781956525e6a553aca318ecb65e861c7935b Mon Sep 17 00:00:00 2001 From: 0xmotto <0xmotto@protonmail.com> Date: Tue, 23 May 2023 17:58:30 +0800 Subject: [PATCH 156/156] fix: check bribe token whitelisted in AutoBribe --- contracts/AutoBribe.sol | 92 +++-------------- contracts/factories/AutoBribeFactory.sol | 6 +- test/AutoBribe.t.sol | 123 ++++++----------------- 3 files changed, 52 insertions(+), 169 deletions(-) diff --git a/contracts/AutoBribe.sol b/contracts/AutoBribe.sol index ffa2e074..3e5c46c2 100644 --- a/contracts/AutoBribe.sol +++ b/contracts/AutoBribe.sol @@ -2,6 +2,7 @@ import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "contracts/interfaces/IERC20.sol"; +import "contracts/interfaces/IVoter.sol"; import "contracts/WrappedBribe.sol"; pragma solidity ^0.8.13; @@ -14,6 +15,7 @@ pragma solidity ^0.8.13; // !!!!!!!!!!!this contract handles multiple bribe tokens, and a single bribe contract!!!!!!!!! contract AutoBribe is Ownable { + address public immutable voter; address public immutable wBribe; address public project; @@ -22,13 +24,8 @@ contract AutoBribe is Ownable { uint256 public nextWeek; address[] public bribeTokens; mapping(address => bool) public bribeTokensDeposited; -<<<<<<< HEAD - mapping(address => uint256) public bribeTokenToAmountEachWeek; - mapping(address => uint256) public bribeTokenToGasRewardEachWeek; -======= mapping(address => uint256) public bribeTokenToWeeksLeft; string public bribeName; ->>>>>>> d984cb02972628a716f7dfab24147acd288ba013 event Deposited( address indexed _bribeToken, @@ -40,7 +37,8 @@ contract AutoBribe is Ownable { event Sealed(uint256 indexed _timestamp); event UnSealed(uint256 indexed _timestamp); - constructor(address _wBribe, address _team, string memory _name) { + constructor(address _voter, address _wBribe, address _team, string memory _name) { + voter = _voter; wBribe = _wBribe; nextWeek = block.timestamp; _transferOwnership(_team); @@ -59,13 +57,6 @@ contract AutoBribe is Ownable { uint256 length = bribeTokens.length; address _bribeToken; for (uint256 i = 0; i < length; ) { -<<<<<<< HEAD - address bribeToken = _bribeTokens[i]; - deposit( - bribeToken, - IERC20(bribeToken).balanceOf(msg.sender) / _weeks, - _weeks -======= _bribeToken = bribeTokens[i]; uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken]; uint256 bribeAmount = balance(_bribeToken) / weeksLeft; @@ -74,7 +65,6 @@ contract AutoBribe is Ownable { WrappedBribe(wBribe).notifyRewardAmount( _bribeToken, bribeAmount - gasReward ->>>>>>> d984cb02972628a716f7dfab24147acd288ba013 ); bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1; unchecked { @@ -97,92 +87,42 @@ contract AutoBribe is Ownable { //Allows project to deposit bribe tokens and set the weeks of which they are divided up into function deposit( address _bribeToken, - uint256 _amountPerWeek, + uint256 _amount, uint256 _weeks ) public { require(msg.sender == project, "only the project can bribe"); - require(_amountPerWeek > 0, "Why are you depositing 0 tokens?"); + require(_amount > 0, "Why are you depositing 0 tokens?"); require(_weeks > 0, "You have to put at least 1 week"); - _safeTransferFrom( - _bribeToken, - msg.sender, - address(this), - _amountPerWeek * _weeks + require( + IVoter(voter).isWhitelisted(_bribeToken), + "Bribe Token is not whitelisted" ); + _safeTransferFrom(_bribeToken, msg.sender, address(this), _amount); uint256 allowance = IERC20(_bribeToken).allowance( address(this), wBribe ); - _safeApprove(_bribeToken, wBribe, allowance + _amountPerWeek * _weeks); + _safeApprove(_bribeToken, wBribe, allowance + _amount); if (!bribeTokensDeposited[_bribeToken]) { bribeTokensDeposited[_bribeToken] = true; bribeTokens.push(_bribeToken); } - uint256 gasRewardPerWeek = _amountPerWeek / 200; - bribeTokenToGasRewardEachWeek[_bribeToken] += gasRewardPerWeek; - - uint256 amountEachWeek = _amountPerWeek - gasRewardPerWeek; - bribeTokenToAmountEachWeek[_bribeToken] += amountEachWeek; - - emit Deposited(_bribeToken, _amountPerWeek * _weeks, _weeks); - } - -<<<<<<< HEAD - function bribe() public { - uint256 length = bribeTokens.length; - uint256 gasRewardPerWeek; - uint256 bribeAmountPerWeek; - uint256 tokenBalance; - address _bribeToken; - for (uint256 i = 0; i < length; ) { - if (block.timestamp >= nextWeek) { - _bribeToken = bribeTokens[i]; - gasRewardPerWeek = bribeTokenToGasRewardEachWeek[_bribeToken]; - bribeAmountPerWeek = bribeTokenToAmountEachWeek[_bribeToken]; - tokenBalance = balance(_bribeToken); - if (tokenBalance >= gasRewardPerWeek + bribeAmountPerWeek) { - _safeTransfer(_bribeToken, msg.sender, gasRewardPerWeek); - WrappedBribe(wBribe).notifyRewardAmount( - _bribeToken, - bribeAmountPerWeek - ); - } else if (tokenBalance > gasRewardPerWeek) { - _safeTransfer(_bribeToken, msg.sender, gasRewardPerWeek); - WrappedBribe(wBribe).notifyRewardAmount( - _bribeToken, - tokenBalance - gasRewardPerWeek - ); - } - } - unchecked { - ++i; - } - } - - emit Bribed(nextWeek, msg.sender); + bribeTokenToWeeksLeft[_bribeToken] += _weeks; - nextWeek = nextWeek + 604800; - } - - function balance(address _bribeToken) public view returns (uint) { - return IERC20(_bribeToken).balanceOf(address(this)); + emit Deposited(_bribeToken, _amount, _weeks); } - //####Admin Functions##### -======= //Allows the project to retrieve their bribe tokens ->>>>>>> d984cb02972628a716f7dfab24147acd288ba013 function emptyOut() public { require(msg.sender == project, "only project can empty out"); require(!depositSealed, "deposit is sealed"); uint256 length = bribeTokens.length; uint256 amount; - address bribeToken; + for (uint256 i = 0; i < length; ) { - bribeToken = bribeTokens[i]; + address bribeToken = bribeTokens[i]; amount = balance(bribeToken); - bribeTokenToGasRewardEachWeek[bribeToken] = 0; - bribeTokenToAmountEachWeek[bribeToken] = 0; + bribeTokenToWeeksLeft[bribeToken] = 0; _safeTransfer(bribeToken, msg.sender, amount); unchecked { diff --git a/contracts/factories/AutoBribeFactory.sol b/contracts/factories/AutoBribeFactory.sol index 679bcd3c..aaf96de4 100644 --- a/contracts/factories/AutoBribeFactory.sol +++ b/contracts/factories/AutoBribeFactory.sol @@ -4,10 +4,12 @@ pragma solidity 0.8.13; import {AutoBribe} from "contracts/AutoBribe.sol"; contract AutoBribeFactory { + address public immutable voter; address public immutable team; address public immutable wBribeFactory; - constructor(address _team, address _wBribeFactory) { + constructor(address _voter, address _team, address _wBribeFactory) { + voter = _voter; team = _team; wBribeFactory = _wBribeFactory; } @@ -17,6 +19,6 @@ contract AutoBribeFactory { string memory name ) external returns (address auto_bribe) { require(wbribe != address(0), "Wrapped bribe not yet created"); - auto_bribe = address(new AutoBribe(wbribe, team, name)); + auto_bribe = address(new AutoBribe(voter, wbribe, team, name)); } } diff --git a/test/AutoBribe.t.sol b/test/AutoBribe.t.sol index 6c5cd673..5d879294 100644 --- a/test/AutoBribe.t.sol +++ b/test/AutoBribe.t.sol @@ -37,6 +37,7 @@ contract AutoBribeTest is BaseTest { amounts[2] = 1e25; mintFlow(owners, amounts); mintLR(owners, amounts); + mintWETH(owners, amounts); VeArtProxy artProxy = new VeArtProxy(); escrow = new VotingEscrow(address(FLOW), address(artProxy), owners[0]); deployPairFactoryAndRouter(); @@ -80,7 +81,12 @@ contract AutoBribeTest is BaseTest { gauge = Gauge(voter.createGauge(address(pair))); xbribe = ExternalBribe(gauge.external_bribe()); wbribe = WrappedBribe(wbribeFactory.createBribe(address(xbribe))); - autoBribe = new AutoBribe(address(wbribe), address(owner), "AUTO"); + autoBribe = new AutoBribe( + address(voter), + address(wbribe), + address(owner), + "AUTO" + ); vm.startPrank(address(owner)); autoBribe.initProject(address(owner2)); @@ -94,15 +100,10 @@ contract AutoBribeTest is BaseTest { } function testCanDepositAndBribeEveryWeek( - uint128 depositAmountPerWeekLR, - uint128 depositAmountPerWeekFLOW, - uint128 depositWeeks + uint256 depositAmountLR, + uint256 depositAmountFLOW, + uint256 depositWeeks ) public { - uint256 depositAmountLR = uint256(depositAmountPerWeekLR) * - uint256(depositWeeks); - uint256 depositAmountFLOW = uint256(depositAmountPerWeekFLOW) * - uint256(depositWeeks); - vm.assume( depositAmountLR > depositWeeks && depositAmountLR <= 1e25 && @@ -117,13 +118,10 @@ contract AutoBribeTest is BaseTest { // Project deposit tokens vm.startPrank(address(owner2)); LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); + FLOW.approve(address(autoBribe), depositAmountFLOW); - autoBribe.deposit( - address(FLOW), - depositAmountPerWeekFLOW, - depositWeeks - ); + autoBribe.deposit(address(FLOW), depositAmountFLOW, depositWeeks); vm.stopPrank(); uint256 balanceBeforeLR = LR.balanceOf(address(this)); @@ -160,66 +158,21 @@ contract AutoBribeTest is BaseTest { ); } -<<<<<<< HEAD - function testCanDepositAllAndBribeEveryWeek(uint256 depositWeeks) public { - vm.assume(depositWeeks <= 52 && depositWeeks > 0); + function testCannotDepositNonWhitelistedTokens() public { vm.warp(block.timestamp + 1 weeks / 2); - // deposit tokens - address[] memory bribeTokens = new address[](2); - bribeTokens[0] = address(LR); - bribeTokens[1] = address(FLOW); - - // Project depoit tokens + // Project deposit tokens vm.startPrank(address(owner2)); LR.approve(address(autoBribe), type(uint256).max); - FLOW.approve(address(autoBribe), type(uint256).max); - autoBribe.depositAll(bribeTokens, depositWeeks); + vm.expectRevert("Bribe Token is not whitelisted"); + autoBribe.deposit(address(WETH), 1e18, 2); vm.stopPrank(); - - uint256 balanceBeforeLR = LR.balanceOf(address(this)); - uint256 balanceBeforeFLOW = FLOW.balanceOf(address(this)); - - for (uint256 i = 0; i < depositWeeks - 1; ) { - autoBribe.bribe(); - vm.warp(block.timestamp + 1 weeks); - - unchecked { - ++i; - } - } - - assertGt(LR.balanceOf(address(autoBribe)), 0); - assertGt(FLOW.balanceOf(address(autoBribe)), 0); - - autoBribe.bribe(); - vm.warp(block.timestamp + 1 weeks); - - assertEq(LR.balanceOf(address(autoBribe)), 0); - assertEq(FLOW.balanceOf(address(autoBribe)), 0); - - assertEq( - LR.balanceOf(address(wbribe)) + - LR.balanceOf(address(this)) - - balanceBeforeLR, - (1e25 / depositWeeks) * depositWeeks - ); - assertEq( - FLOW.balanceOf(address(wbribe)) + - FLOW.balanceOf(address(this)) - - balanceBeforeFLOW, - (1e25 / depositWeeks) * depositWeeks - ); } -======= ->>>>>>> d984cb02972628a716f7dfab24147acd288ba013 function testRedeposit( - uint128 depositAmountPerWeekLR, - uint128 depositWeeks + uint256 depositAmountLR, + uint256 depositWeeks ) public { - uint256 depositAmountLR = uint256(depositAmountPerWeekLR) * - uint256(depositWeeks); vm.assume( depositAmountLR > depositWeeks && depositAmountLR <= 1e24 && @@ -231,8 +184,8 @@ contract AutoBribeTest is BaseTest { // Project deposit tokens vm.startPrank(address(owner2)); - LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); + LR.approve(address(autoBribe), type(uint256).max); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); vm.stopPrank(); uint256 balanceBeforeLR = LR.balanceOf(address(this)); @@ -242,7 +195,7 @@ contract AutoBribeTest is BaseTest { vm.startPrank(address(owner2)); LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); vm.stopPrank(); for (uint256 i = 0; i < depositWeeks * 2 - 2; ) { @@ -254,7 +207,7 @@ contract AutoBribeTest is BaseTest { } } - assertGe(LR.balanceOf(address(autoBribe)), 0); + assertGt(LR.balanceOf(address(autoBribe)), 0); autoBribe.bribe(); vm.warp(block.timestamp + 1 weeks); @@ -294,19 +247,14 @@ contract AutoBribeTest is BaseTest { } function testEmptyOut( - uint128 depositAmountPerWeekLR, - uint128 depositAmountPerWeekFLOW, - uint128 depositWeeks + uint256 depositAmountLR, + uint256 depositAmountFLOW, + uint256 depositWeeks ) public { - uint256 depositAmountLR = uint256(depositAmountPerWeekLR) * - uint256(depositWeeks); - uint256 depositAmountFLOW = uint256(depositAmountPerWeekFLOW) * - uint256(depositWeeks); - vm.assume( - depositAmountLR > uint256(depositWeeks) && + depositAmountLR > depositWeeks && depositAmountLR <= 1e25 && - depositAmountFLOW > uint256(depositWeeks) && + depositAmountFLOW > depositWeeks && depositAmountFLOW <= 1e25 && depositWeeks > 0 && depositWeeks < 52 @@ -317,14 +265,10 @@ contract AutoBribeTest is BaseTest { // Project deposit tokens vm.startPrank(address(owner2)); LR.approve(address(autoBribe), depositAmountLR); - autoBribe.deposit(address(LR), depositAmountPerWeekLR, depositWeeks); + autoBribe.deposit(address(LR), depositAmountLR, depositWeeks); FLOW.approve(address(autoBribe), depositAmountFLOW); - autoBribe.deposit( - address(FLOW), - depositAmountPerWeekFLOW, - depositWeeks - ); + autoBribe.deposit(address(FLOW), depositAmountFLOW, depositWeeks); autoBribe.seal(); vm.stopPrank(); @@ -348,11 +292,8 @@ contract AutoBribeTest is BaseTest { autoBribe.emptyOut(); vm.stopPrank(); - assertEq(autoBribe.bribeTokenToGasRewardEachWeek(address(LR)), 0); - assertEq(autoBribe.bribeTokenToGasRewardEachWeek(address(FLOW)), 0); - - assertEq(autoBribe.bribeTokenToAmountEachWeek(address(LR)), 0); - assertEq(autoBribe.bribeTokenToAmountEachWeek(address(FLOW)), 0); + assertEq(autoBribe.bribeTokenToWeeksLeft(address(LR)), 0); + assertEq(autoBribe.bribeTokenToWeeksLeft(address(FLOW)), 0); assertEq(LR.balanceOf(address(autoBribe)), 0); assertEq(FLOW.balanceOf(address(autoBribe)), 0);