From 2c95e1b9aac6ffc11e458aea2548d5a83abb2f57 Mon Sep 17 00:00:00 2001 From: deo Date: Mon, 27 Nov 2023 19:10:54 -0500 Subject: [PATCH 1/8] feat: swapper v2 --- foundry.toml | 2 +- package.json | 4 +- remappings.txt | 4 +- solidity/contracts/Greeter.sol | 59 - solidity/contracts/Swapper.sol | 89 + solidity/contracts/SwapperV2.sol | 93 + solidity/interfaces/IGreeter.sol | 75 - solidity/interfaces/ISwapper.sol | 24 + solidity/interfaces/ISwapperV2.sol | 24 + solidity/scripts/Deploy.sol | 48 +- solidity/test/integration/Greeter.t.sol | 16 - solidity/test/integration/IntegrationBase.sol | 24 - solidity/test/unit/Greeter.t.sol | 99 - solidity/test/unit/Swapper.t.sol | 181 ++ solidity/test/unit/SwapperV2.t.sol | 147 ++ solidity/test/utils/DSTestFull.sol | 2 +- yarn.lock | 1938 ++++++++++++++++- 17 files changed, 2495 insertions(+), 334 deletions(-) delete mode 100644 solidity/contracts/Greeter.sol create mode 100644 solidity/contracts/Swapper.sol create mode 100644 solidity/contracts/SwapperV2.sol delete mode 100644 solidity/interfaces/IGreeter.sol create mode 100644 solidity/interfaces/ISwapper.sol create mode 100644 solidity/interfaces/ISwapperV2.sol delete mode 100644 solidity/test/integration/Greeter.t.sol delete mode 100644 solidity/test/integration/IntegrationBase.sol delete mode 100644 solidity/test/unit/Greeter.t.sol create mode 100644 solidity/test/unit/Swapper.t.sol create mode 100644 solidity/test/unit/SwapperV2.t.sol diff --git a/foundry.toml b/foundry.toml index 00f9bd4a..b5cec567 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,7 +8,7 @@ number_underscore = 'thousands' multiline_func_header = 'params_first' [profile.default] -solc = '0.8.19' +solc = '0.8.20' evm_version = 'paris' src = 'solidity' test = 'solidity/test' diff --git a/package.json b/package.json index ea867a43..3bee4938 100644 --- a/package.json +++ b/package.json @@ -32,10 +32,12 @@ "package.json": "sort-package-json" }, "dependencies": { + "@openzeppelin/contracts": "^5.0.0", "ds-test": "github:dapphub/ds-test#e282159", "forge-std": "github:foundry-rs/forge-std#v1.5.6", "isolmate": "github:defi-wonderland/isolmate#59e1804", - "prb/test": "github:paulrberg/prb-test#a245c71" + "prb/test": "github:paulrberg/prb-test#a245c71", + "uniswap": "^0.0.1" }, "devDependencies": { "@commitlint/cli": "17.0.3", diff --git a/remappings.txt b/remappings.txt index 89bb6bd4..06a545aa 100644 --- a/remappings.txt +++ b/remappings.txt @@ -5,4 +5,6 @@ isolmate/=node_modules/isolmate/src contracts/=solidity/contracts interfaces/=solidity/interfaces -test/=solidity/test \ No newline at end of file +test/=solidity/test +@openzeppelin/=node_modules/@openzeppelin +@uniswap/=node_modules/uniswap/uniswap/contracts \ No newline at end of file diff --git a/solidity/contracts/Greeter.sol b/solidity/contracts/Greeter.sol deleted file mode 100644 index 053e933e..00000000 --- a/solidity/contracts/Greeter.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.19; - -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; -import {IGreeter} from 'interfaces/IGreeter.sol'; - -contract Greeter is IGreeter { - /** - * @notice Empty string for revert checks - * @dev result of doing keccak256(bytes('')) - */ - bytes32 internal constant _EMPTY_STRING = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; - - /// @inheritdoc IGreeter - address public immutable OWNER; - - /// @inheritdoc IGreeter - string public greeting; - - /// @inheritdoc IGreeter - IERC20 public token; - - /** - * @notice Defines the owner to the msg.sender and sets the initial greeting - * @param _greeting Initial greeting - * @param _token Initial token - */ - constructor(string memory _greeting, IERC20 _token) { - OWNER = msg.sender; - token = _token; - setGreeting(_greeting); - } - - /// @inheritdoc IGreeter - function setGreeting(string memory _greeting) public onlyOwner { - if (keccak256(bytes(_greeting)) == _EMPTY_STRING) { - revert Greeter_InvalidGreeting(); - } - - greeting = _greeting; - emit GreetingSet(_greeting); - } - - /// @inheritdoc IGreeter - function greet() external view returns (string memory _greeting, uint256 _balance) { - _greeting = greeting; - _balance = token.balanceOf(msg.sender); - } - - /** - * @notice Reverts in case the function was not called by the owner of the contract - */ - modifier onlyOwner() { - if (msg.sender != OWNER) { - revert Greeter_OnlyOwner(); - } - _; - } -} diff --git a/solidity/contracts/Swapper.sol b/solidity/contracts/Swapper.sol new file mode 100644 index 00000000..bb64d393 --- /dev/null +++ b/solidity/contracts/Swapper.sol @@ -0,0 +1,89 @@ +pragma solidity ^0.8.19; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; +import {ISwapper} from '../interfaces/ISwapper.sol'; + +/// @title Swapper contract +/// @author 0xdeo +/// @notice Allows friends to pool their tokens and make a swap +/// @notice Requires a trusted third party to provide initial liquidity +contract Swapper is ISwapper, Ownable { + using SafeERC20 for IERC20; + + IERC20 fromToken; + IERC20 toToken; + + uint256 netLiquidity; + + mapping(uint256 => Swap) public swaps; + uint256 swapId; + + constructor(address _fromToken, address _toToken) Ownable(msg.sender) { + fromToken = IERC20(_fromToken); + toToken = IERC20(_toToken); + } + + /// @notice Can only provide tokens when swap hasn't been done yet + /// @notice Cannot provide tokens if fromToken balance will exceed contract's toToken balance + /// @notice User's deposit gets recorded in latest epoch, and the swapId recording his deposit is then returned + /// @param _amount Amount of fromTokens to provide + function provide(uint256 _amount) public returns (uint256) { + if (netLiquidity < _amount) { + revert InsufficientLiquidity(); + } + + swaps[swapId].balances[msg.sender] += _amount; + netLiquidity -= _amount; + + fromToken.safeTransferFrom(msg.sender, address(this), _amount); + + emit Provide(msg.sender, _amount, swapId); + return swapId; + } + + /// @notice Initiates swap by sealing off further deposits and allowing withdrawals of toTokens, for that swapId's epoch + /// @notice Sends any deposited fromTokens to the owner of the contract who provided initial liquidity + function swap() public onlyOwner { + swaps[swapId].swapped = true; + swapId++; + + fromToken.safeTransfer(owner(), fromToken.balanceOf(address(this))); + + emit Swapped(swapId - 1); + } + + /// @notice User must have nonzero balance + /// @notice If swap has been initiated, he receives toTokens in 1:1 ratio to his deposit + /// @notice Otherwise he is refunded the full amount he deposited. + /// @param _swapId ID designating epoch user's deposit belonged to + function withdraw(uint256 _swapId) public { + uint256 balance = swaps[_swapId].balances[msg.sender]; + swaps[_swapId].balances[msg.sender] = 0; + + if (balance == 0) { + revert ZeroBalance(); + } + + bool _refunded; + if (swaps[_swapId].swapped) { + toToken.safeTransfer(msg.sender, balance); + } else { + netLiquidity += balance; + _refunded = true; + fromToken.safeTransfer(msg.sender, balance); + } + + emit Withdraw(msg.sender, balance, _swapId, _refunded); + } + + /// @notice Can only provide tokens when swap hasn't been done yet + /// @param _liquidity amount of toTokens to provide as liquidity + function provideLiquidity(uint256 _liquidity) public onlyOwner { + netLiquidity += _liquidity; + toToken.safeTransferFrom(msg.sender, address(this), _liquidity); + + emit LiquidityAdded(_liquidity); + } +} diff --git a/solidity/contracts/SwapperV2.sol b/solidity/contracts/SwapperV2.sol new file mode 100644 index 00000000..394dedb4 --- /dev/null +++ b/solidity/contracts/SwapperV2.sol @@ -0,0 +1,93 @@ +pragma solidity ^0.8.19; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; +import {IUniswapV2Router01} from '@uniswap/periphery/interfaces/IUniswapV2Router01.sol'; +import {IUniswapV2Pair} from '@uniswap/core/interfaces/IUniswapV2Pair.sol'; +import {ISwapperV2} from '../interfaces/ISwapperV2.sol'; + +/// @title Swapper contract V2 +/// @author 0xdeo +/// @notice Allows friends to pool their tokens and make a swap +/// @notice Routes swaps thru Uniswap +contract SwapperV2 is ISwapperV2, Ownable { + using SafeERC20 for IERC20; + + IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + IERC20 constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); + + IUniswapV2Router01 constant router = IUniswapV2Router01(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); + IUniswapV2Pair constant pair = IUniswapV2Pair(0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11); + + mapping(uint256 => Swap) public swaps; + uint256 swapId; + + constructor() Ownable(msg.sender) {} + + /// @notice Can only provide tokens when swap hasn't been done yet + /// @notice Cannot provide tokens if fromToken balance will exceed contract's toToken balance + /// @notice User's deposit gets recorded in latest epoch, and the swapId recording his deposit is then returned + function provide() public payable returns (uint256) { + swaps[swapId].balances[msg.sender] += msg.value; + + emit Provide(msg.sender, msg.value, swapId); + return swapId; + } + + /// @notice Initiates swap by sealing off further deposits and allowing withdrawals of toTokens, for that swapId's epoch + /// @notice Sends any deposited fromTokens to the owner of the contract who provided initial liquidity + function swap() public onlyOwner { + address[] memory _path = new address[](2); + _path[0] = address(WETH); + _path[1] = address(DAI); + (uint256 _reserve0, uint256 _reserve1,) = pair.getReserves(); + uint256 _amountOutMin; + uint256 _amountOut = DAI.balanceOf(address(this)); + uint256 _amountIn = address(this).balance; + + swaps[swapId].swapped = true; + swapId++; + + if (address(WETH) == pair.token0()) { + _amountOutMin = router.getAmountOut(address(this).balance, _reserve0, _reserve1); + } else { + _amountOutMin = router.getAmountOut(address(this).balance, _reserve1, _reserve0); + } + + // 1% slippage to prevent frontrunning + _amountOut = router.swapExactETHForTokens{value: address(this).balance}( + _amountOutMin * 99 / 100, _path, address(this), block.timestamp + )[1]; + + //_amountOut = DAI.balanceOf(address(this)) - _amountOut; + swaps[swapId - 1].totalOut = _amountOut; + swaps[swapId - 1].totalIn = _amountIn; + + emit Swapped(swapId - 1); + } + + /// @notice User must have nonzero balance + /// @notice If swap has been initiated, he receives toTokens in 1:1 ratio to his deposit + /// @notice Otherwise he is refunded the full amount he deposited. + /// @param _swapId ID designating epoch user's deposit belonged to + function withdraw(uint256 _swapId) public { + uint256 balance = swaps[_swapId].balances[msg.sender]; + swaps[_swapId].balances[msg.sender] = 0; + + if (balance == 0) { + revert ZeroBalance(); + } + + bool _refunded; + if (swaps[_swapId].swapped) { + balance = (balance * swaps[_swapId].totalOut) / swaps[_swapId].totalIn; + DAI.safeTransfer(msg.sender, balance); + } else { + _refunded = true; + payable(msg.sender).transfer(balance); + } + + emit Withdraw(msg.sender, balance, _swapId, _refunded); + } +} diff --git a/solidity/interfaces/IGreeter.sol b/solidity/interfaces/IGreeter.sol deleted file mode 100644 index 10877023..00000000 --- a/solidity/interfaces/IGreeter.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; - -/** - * @title Greeter Contract - * @author Wonderland - * @notice This is a basic contract created in order to portray some - * best practices and foundry functionality. - */ -interface IGreeter { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Greeting has changed - * @param _greeting The new greeting - */ - event GreetingSet(string _greeting); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Throws if the function was called by someone else than the owner - */ - error Greeter_OnlyOwner(); - - /** - * @notice Throws if the greeting set is invalid - * @dev Empty string is an invalid greeting - */ - error Greeter_InvalidGreeting(); - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the owner of the contract - * @dev The owner will always be the deployer of the contract - * @return _owner The owner of the contract - */ - function OWNER() external view returns (address _owner); - - /** - * @notice Returns the previously set greeting - * @return _greet The greeting - */ - function greeting() external view returns (string memory _greet); - - /** - * @notice Returns the token used to greet callers - * @return _token The address of the token - */ - function token() external view returns (IERC20 _token); - - /** - * @notice Greets the caller - * - * @return _greeting The greeting - * @return _balance Current token balance of the caller - */ - function greet() external view returns (string memory _greeting, uint256 _balance); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - /** - * @notice Sets a new greeting - * @dev Only callable by the owner - * @param _newGreeting The new greeting to be set - */ - function setGreeting(string memory _newGreeting) external; -} diff --git a/solidity/interfaces/ISwapper.sol b/solidity/interfaces/ISwapper.sol new file mode 100644 index 00000000..596112d2 --- /dev/null +++ b/solidity/interfaces/ISwapper.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.8.19; + +/// @title Swapper interface +/// @author 0xdeo +/// @notice Defines custom errors, function signatures and a struct for the swapper contract +interface ISwapper { + function provide(uint256 _amount) external returns (uint256); + function swap() external; + function withdraw(uint256 _swapId) external; + function provideLiquidity(uint256 _liquidity) external; + + error InsufficientLiquidity(); + error ZeroBalance(); + + event Provide(address _depositor, uint256 _amount, uint256 _swapId); + event Swapped(uint256 _swapId); + event Withdraw(address _depositor, uint256 _amount, uint256 _swapId, bool _refunded); + event LiquidityAdded(uint256 _liquidity); + + struct Swap { + bool swapped; + mapping(address => uint256) balances; + } +} diff --git a/solidity/interfaces/ISwapperV2.sol b/solidity/interfaces/ISwapperV2.sol new file mode 100644 index 00000000..526db008 --- /dev/null +++ b/solidity/interfaces/ISwapperV2.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.8.19; + +/// @title Swapper interface +/// @author 0xdeo +/// @notice Defines custom errors, function signatures and a struct for the swapper contract +interface ISwapperV2 { + function provide() external payable returns (uint256); + function swap() external; + function withdraw(uint256 _swapId) external; + + error ZeroBalance(); + + event Provide(address _depositor, uint256 _amount, uint256 _swapId); + event Swapped(uint256 _swapId); + event Withdraw(address _depositor, uint256 _amount, uint256 _swapId, bool _refunded); + event LiquidityAdded(uint256 _liquidity); + + struct Swap { + bool swapped; + uint256 totalIn; + uint256 totalOut; + mapping(address => uint256) balances; + } +} diff --git a/solidity/scripts/Deploy.sol b/solidity/scripts/Deploy.sol index 6714510d..c55ab519 100644 --- a/solidity/scripts/Deploy.sol +++ b/solidity/scripts/Deploy.sol @@ -1,30 +1,30 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.19; +// // SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; -import {Script} from 'forge-std/Script.sol'; -import {Greeter} from 'contracts/Greeter.sol'; -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; +// import {Script} from 'forge-std/Script.sol'; +// import {Greeter} from 'contracts/Greeter.sol'; +// import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; -abstract contract Deploy is Script { - function _deploy(string memory greeting, IERC20 token) internal { - vm.startBroadcast(); - new Greeter(greeting, token); - vm.stopBroadcast(); - } -} +// abstract contract Deploy is Script { +// function _deploy(string memory greeting, IERC20 token) internal { +// vm.startBroadcast(); +// new Greeter(greeting, token); +// vm.stopBroadcast(); +// } +// } -contract DeployMainnet is Deploy { - function run() external { - IERC20 weth = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); +// contract DeployMainnet is Deploy { +// function run() external { +// IERC20 weth = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); - _deploy('some real greeting', weth); - } -} +// _deploy('some real greeting', weth); +// } +// } -contract DeployGoerli is Deploy { - function run() external { - IERC20 weth = IERC20(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6); +// contract DeployGoerli is Deploy { +// function run() external { +// IERC20 weth = IERC20(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6); - _deploy('some test greeting', weth); - } -} +// _deploy('some test greeting', weth); +// } +// } diff --git a/solidity/test/integration/Greeter.t.sol b/solidity/test/integration/Greeter.t.sol deleted file mode 100644 index 674b07d1..00000000 --- a/solidity/test/integration/Greeter.t.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -import {IntegrationBase} from 'test/integration/IntegrationBase.sol'; - -contract IntegrationGreeter is IntegrationBase { - function test_Greet() public { - uint256 _whaleBalance = _dai.balanceOf(_daiWhale); - - vm.prank(_daiWhale); - (string memory _greeting, uint256 _balance) = _greeter.greet(); - - assertEq(_whaleBalance, _balance); - assertEq(_initialGreeting, _greeting); - } -} diff --git a/solidity/test/integration/IntegrationBase.sol b/solidity/test/integration/IntegrationBase.sol deleted file mode 100644 index 2c1646dc..00000000 --- a/solidity/test/integration/IntegrationBase.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -import {DSTestFull} from 'test/utils/DSTestFull.sol'; -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; - -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; - -contract IntegrationBase is DSTestFull { - uint256 internal constant _FORK_BLOCK = 15_452_788; - - string internal _initialGreeting = 'hola'; - address internal _user = _label('user'); - address internal _owner = _label('owner'); - address internal _daiWhale = 0x42f8CA49E88A8fd8F0bfA2C739e648468b8f9dec; - IERC20 internal _dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); - IGreeter internal _greeter; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), _FORK_BLOCK); - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _dai); - } -} diff --git a/solidity/test/unit/Greeter.t.sol b/solidity/test/unit/Greeter.t.sol deleted file mode 100644 index 06df96ae..00000000 --- a/solidity/test/unit/Greeter.t.sol +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.19; - -import {IERC20} from 'isolmate/interfaces/tokens/IERC20.sol'; -import {DSTestFull} from 'test/utils/DSTestFull.sol'; -import {Greeter, IGreeter} from 'contracts/Greeter.sol'; - -abstract contract Base is DSTestFull { - address internal _owner = _label('owner'); - IERC20 internal _token = IERC20(_mockContract('token')); - string internal _initialGreeting = 'hola'; - bytes32 internal _emptyString = keccak256(bytes('')); - Greeter internal _greeter; - - function setUp() public virtual { - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); - } -} - -contract UnitGreeterConstructor is Base { - function test_OwnerSet(address _owner) public { - vm.prank(_owner); - _greeter = new Greeter(_initialGreeting, _token); - - assertEq(_greeter.OWNER(), _owner); - } - - function test_TokenSet(IERC20 _token) public { - _greeter = new Greeter(_initialGreeting, _token); - - assertEq(address(_greeter.token()), address(_token)); - } - - function test_GreetingSet(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - - _greeter = new Greeter(_greeting, _token); - assertEq(_greeting, _greeter.greeting()); - } -} - -contract UnitGreeterSetGreeting is Base { - event GreetingSet(string _greeting); - - function setUp() public override { - super.setUp(); - vm.startPrank(_owner); - } - - function test_RevertIfNotOwner(address _caller, string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - vm.assume(_caller != _owner); - - vm.stopPrank(); - vm.prank(_caller); - - vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); - _greeter.setGreeting(_greeting); - } - - function test_RevertIfEmptyGreeting() public { - vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); - _greeter.setGreeting(''); - } - - function test_SetGreeting(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - _greeter.setGreeting(_greeting); - - assertEq(_greeting, _greeter.greeting()); - } - - function test_EmitEvent(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - - _expectEmitNoIndex(); - emit GreetingSet(_greeting); - - _greeter.setGreeting(_greeting); - } -} - -contract UnitGreeterGreet is Base { - function test_GetGreeting() public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(0)); - - (string memory _greeting,) = _greeter.greet(); - assertEq(_initialGreeting, _greeting); - } - - function test_GetTokenBalance(address _caller, uint256 _balance) public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector, _caller), abi.encode(_balance)); - - vm.prank(_caller); - (, uint256 _greetBalance) = _greeter.greet(); - assertEq(_balance, _greetBalance); - } -} diff --git a/solidity/test/unit/Swapper.t.sol b/solidity/test/unit/Swapper.t.sol new file mode 100644 index 00000000..64f94f8f --- /dev/null +++ b/solidity/test/unit/Swapper.t.sol @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import {Test, console2} from 'forge-std/Test.sol'; +import {Swapper} from '../../contracts/Swapper.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +error InsufficientLiquidity(); +error ZeroBalance(); + +contract SwapperTest is Test { + Swapper public swapper; + + IERC20 fromToken; + IERC20 toToken; + + address alice = makeAddr('alice'); + address bob = makeAddr('bob'); + address eve = makeAddr('eve'); + + uint256 constant LIQUIDITY = 100e18; + + function setUp() public { + vm.createSelectFork(vm.envString('MAINNET_RPC')); + fromToken = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); // USDC token + toToken = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); // DAI token + + swapper = new Swapper(address(fromToken), address(toToken)); + + deal(address(toToken), address(this), LIQUIDITY); + toToken.approve(address(swapper), LIQUIDITY); + swapper.provideLiquidity(LIQUIDITY); + + deal(address(fromToken), alice, 1e18); + deal(address(fromToken), bob, 2e18); + deal(address(fromToken), eve, 10e18); + } + + // Basic check that tokens are correctly provided to the swapper when providing + function testProvide() public { + vm.startPrank(alice); + fromToken.approve(address(swapper), 1e18); + swapper.provide(1e18); + + assertEq(fromToken.balanceOf(address(swapper)), 1e18); + } + + // User should be able to get a refund for any deposited tokens not yet swapped + function testRefund() public { + vm.startPrank(alice); + fromToken.approve(address(swapper), 1e18); + uint256 _swapId = swapper.provide(1e18); + swapper.withdraw(_swapId); + + assertEq(fromToken.balanceOf(alice), 1e18); + } + + // Alice should be allowed to swap her tokens and receive the correct amount of toTokens + // Contract deployer receives all excess tokens + function testSwap() public { + vm.prank(alice); + fromToken.approve(address(swapper), 1e18); + + vm.prank(alice); + uint256 _swapId = swapper.provide(1e18); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + assertEq(toToken.balanceOf(alice), 1e18); + assertEq(fromToken.balanceOf(address(this)), 1e18); + } + + // Testing swaps over multiple epochs + function testMultipleEpochs() public { + vm.prank(alice); + fromToken.approve(address(swapper), 1e18); + + vm.prank(alice); + uint256 _swapId = swapper.provide(1e18); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + vm.prank(bob); + fromToken.approve(address(swapper), 1e18); + + vm.prank(bob); + _swapId = swapper.provide(1e18); + + swapper.swap(); + + vm.prank(bob); + swapper.withdraw(_swapId); + + assertEq(toToken.balanceOf(alice), 1e18); + assertEq(toToken.balanceOf(bob), 1e18); + assertEq(fromToken.balanceOf(address(this)), 2e18); + } + + // Testing multiple swaps over same epoch + // alice and bob do the swap and get toTokens + // eve gets a refund + function testMultipleSwaps() public { + vm.prank(alice); + fromToken.approve(address(swapper), 1e18); + + vm.prank(alice); + uint256 _swapId = swapper.provide(1e18); + + vm.prank(bob); + fromToken.approve(address(swapper), 1e18); + + vm.prank(bob); + _swapId = swapper.provide(1e18); + + vm.prank(eve); + fromToken.approve(address(swapper), 1e18); + + vm.prank(eve); + _swapId = swapper.provide(1e18); + + vm.prank(eve); + swapper.withdraw(_swapId); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + vm.prank(bob); + swapper.withdraw(_swapId); + + assertEq(toToken.balanceOf(alice), 1e18); + assertEq(toToken.balanceOf(bob), 1e18); + assertEq(toToken.balanceOf(eve), 0); + assertEq(fromToken.balanceOf(address(this)), 2e18); + } + + // Users cannot provide more tokens to be swapped than the total current liquidity + function testLiquidity() public { + deal(address(fromToken), alice, LIQUIDITY + 1); + + vm.startPrank(alice); + fromToken.approve(address(swapper), LIQUIDITY + 1); + swapper.provide(LIQUIDITY); + + vm.expectRevert(); + swapper.provide(1); + } + + function testFuzz_swap(uint256 _amount, bool swap) public { + _amount = bound(_amount, 1, LIQUIDITY); + deal(address(fromToken), alice, _amount); + + vm.prank(alice); + fromToken.approve(address(swapper), _amount); + + vm.prank(alice); + + uint256 _swapId = swapper.provide(_amount); + + if (swap) { + swapper.swap(); + } + + vm.prank(alice); + swapper.withdraw(_swapId); + + if (swap) { + assertEq(fromToken.balanceOf(address(this)), _amount); + assertEq(toToken.balanceOf(alice), _amount); + } else { + assertEq(fromToken.balanceOf(alice), _amount); + } + } +} diff --git a/solidity/test/unit/SwapperV2.t.sol b/solidity/test/unit/SwapperV2.t.sol new file mode 100644 index 00000000..2251271e --- /dev/null +++ b/solidity/test/unit/SwapperV2.t.sol @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import {Test, console2} from 'forge-std/Test.sol'; +import {SwapperV2} from '../../contracts/SwapperV2.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +error InsufficientLiquidity(); +error ZeroBalance(); + +contract SwapperV2Test is Test { + SwapperV2 public swapper; + + IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + IERC20 constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); + + address alice = makeAddr('alice'); + address bob = makeAddr('bob'); + address eve = makeAddr('eve'); + + uint256 constant LIQUIDITY = 100e18; + + function setUp() public { + vm.createSelectFork(vm.envString('MAINNET_RPC')); + + swapper = new SwapperV2(); + + deal(address(this), LIQUIDITY); + + deal(alice, 1e18); + deal(bob, 2e18); + deal(eve, 10e18); + } + + //Basic check that tokens are correctly provided to the swapper when providing + function testProvide() public { + vm.startPrank(alice); + swapper.provide{value: 1e18}(); + + assertEq(address(swapper).balance, 1e18); + } + + // User should be able to get a refund for any deposited tokens not yet swapped + function testRefund() public { + vm.startPrank(alice); + uint256 _swapId = swapper.provide{value: 1e18}(); + swapper.withdraw(_swapId); + + assertEq(alice.balance, 1e18); + } + + // Alice should be allowed to swap her tokens and receive the correct amount of toTokens + // Contract deployer receives all excess tokens + function testSwap() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertEq(DAI.balanceOf(address(this)), 0); + } + + // Testing swaps over multiple epochs + function testMultipleEpochs() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + vm.prank(bob); + _swapId = swapper.provide{value: 1e18}(); + + swapper.swap(); + + vm.prank(bob); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertGt(DAI.balanceOf(bob), 0); + assertEq(DAI.balanceOf(address(this)), 0); + } + + // Testing multiple swaps over same epoch + // alice and bob do the swap and get toTokens + // eve gets a refund + function testMultipleSwaps() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + vm.prank(bob); + + _swapId = swapper.provide{value: 1e18}(); + + vm.prank(eve); + + _swapId = swapper.provide{value: 1e18}(); + + vm.prank(eve); + swapper.withdraw(_swapId); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + vm.prank(bob); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertGt(DAI.balanceOf(bob), 0); + assertEq(eve.balance, 10e18); + assertEq(DAI.balanceOf(address(this)), 0); + } + + function testFuzz_swap(uint256 _amount, bool swap) public { + _amount = bound(_amount, 1, 1e21); + deal(alice, _amount); + + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: _amount}(); + + if (swap) { + swapper.swap(); + } + + vm.prank(alice); + swapper.withdraw(_swapId); + + if (swap) { + assertEq(DAI.balanceOf(address(this)), 0); + assertGt(DAI.balanceOf(alice), 0); + } else { + assertEq(alice.balance, _amount); + } + } +} diff --git a/solidity/test/utils/DSTestFull.sol b/solidity/test/utils/DSTestFull.sol index c1bd8568..b74a7496 100644 --- a/solidity/test/utils/DSTestFull.sol +++ b/solidity/test/utils/DSTestFull.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.19; +pragma solidity ^0.8.19; import {PRBTest} from 'prb/test/PRBTest.sol'; diff --git a/yarn.lock b/yarn.lock index 7b4b14ff..047ed209 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,42 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@chainsafe/as-sha256@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" + integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== + +"@chainsafe/persistent-merkle-tree@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" + integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/persistent-merkle-tree@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" + integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + +"@chainsafe/ssz@^0.10.0": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" + integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.5.0" + +"@chainsafe/ssz@^0.9.2": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" + integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.4.2" + case "^1.6.3" + "@commitlint/cli@17.0.3": version "17.0.3" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-17.0.3.tgz#50be9d9a8d79f6c47bfd2703638fe65215eb2526" @@ -191,6 +227,353 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.1.2", "@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.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.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.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.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.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.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.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.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", "@ethersproject/providers@^5.7.1", "@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.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.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" + +"@fastify/busboy@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" + integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== + "@jridgewell/resolve-uri@^3.0.3": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" @@ -209,6 +592,27 @@ "@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" + +"@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== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -230,6 +634,301 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@nomicfoundation/ethereumjs-block@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" + integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + +"@nomicfoundation/ethereumjs-blockchain@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" + integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-ethash" "3.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + 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@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" + integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== + dependencies: + "@nomicfoundation/ethereumjs-util" "9.0.2" + crc-32 "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" + integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-evm@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" + integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== + dependencies: + "@ethersproject/providers" "^5.7.1" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" + integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== + +"@nomicfoundation/ethereumjs-statemanager@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" + integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== + dependencies: + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + ethers "^5.7.1" + js-sdsl "^4.1.4" + +"@nomicfoundation/ethereumjs-trie@6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" + integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + "@types/readable-stream" "^2.3.13" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" + integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== + dependencies: + "@chainsafe/ssz" "^0.9.2" + "@ethersproject/providers" "^5.7.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@9.0.2": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" + integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== + dependencies: + "@chainsafe/ssz" "^0.10.0" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-vm@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" + integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== + dependencies: + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-blockchain" "7.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-evm" "2.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-statemanager" "2.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + 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" + +"@openzeppelin/contracts@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.0.tgz#ee0e4b4564f101a5c4ee398cd4d73c0bd92b289c" + integrity sha512-bv2sdS6LKqVVMLI5+zqnNrNU/CA+6z6CmwFXm/MzmOPBRSO5reEJN7z0Gbzvs0/bv/MZZXNklubpwy3v2+azsw== + +"@scure/base@~1.1.0": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" + integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== + +"@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" + "@solidity-parser/parser@^0.14.1": version "0.14.5" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" @@ -264,6 +963,20 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== +"@types/bn.js@^4.11.3": + 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.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" + integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== + dependencies: + "@types/node" "*" + "@types/glob@^7.1.1": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -272,6 +985,11 @@ "@types/minimatch" "*" "@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/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" @@ -292,6 +1010,28 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== +"@types/pbkdf2@^3.0.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.2.tgz#2dc43808e9985a2c69ff02e2d2027bd4fe33e8dc" + integrity sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew== + dependencies: + "@types/node" "*" + +"@types/readable-stream@^2.3.13": + version "2.3.15" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" + integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + +"@types/secp256k1@^4.0.1": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf" + integrity sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ== + dependencies: + "@types/node" "*" + JSONStream@^1.0.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -300,6 +1040,19 @@ JSONStream@^1.0.4: jsonparse "^1.2.0" through ">=2.2.7 <3" +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" + acorn-jsx@^5.0.0: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -320,6 +1073,23 @@ acorn@^8.4.1: 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== + +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" @@ -348,6 +1118,16 @@ ajv@^8.0.1, ajv@^8.11.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.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@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -414,6 +1194,14 @@ antlr4ts@^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" @@ -466,6 +1254,48 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base-x@^3.0.2: + 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== + +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.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== + +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== + +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== + +bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: + 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.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== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -481,13 +1311,84 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2: +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.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.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" + +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-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@^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" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -526,6 +1427,21 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +case@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" + integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== + +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== + chalk@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" @@ -553,6 +1469,45 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +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" + +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== + +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" + +classic-level@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" + integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "^2.2.2" + 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" @@ -593,6 +1548,15 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== +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" + cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -631,11 +1595,21 @@ colorette@^2.0.19: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== +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== + commander@2.18.0: version "2.18.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== +commander@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + commander@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" @@ -683,6 +1657,11 @@ conventional-commits-parser@^3.2.2: split2 "^3.0.0" through2 "^4.0.0" +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== + cosmiconfig-typescript-loader@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz#c4259ce474c9df0f32274ed162c0447c951ef073" @@ -708,6 +1687,34 @@ cosmiconfig@^8.0.0: parse-json "^5.0.0" path-type "^4.0.0" +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-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.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" @@ -738,7 +1745,7 @@ dargs@^7.0.0: resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -debug@^4.0.1, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -758,11 +1765,21 @@ decamelize@^1.1.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== + deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +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== + detect-indent@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" @@ -773,6 +1790,11 @@ detect-newline@3.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +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" @@ -808,6 +1830,19 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +elliptic@6.5.4, elliptic@^6.5.2, 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@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -823,6 +1858,19 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +enquirer@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.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== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -835,6 +1883,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +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.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -945,6 +1998,110 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +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" + +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-util@^6.0.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" + +ethers@^5.7.1: + 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-util@0.1.6, 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" + +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" + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1043,6 +2200,21 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +find-up@5.0.0, 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@^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-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -1051,14 +2223,6 @@ find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -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" - flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -1068,15 +2232,46 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +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== + flatted@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +follow-redirects@^1.12.1: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + "forge-std@github:foundry-rs/forge-std#v1.5.6": version "1.5.6" resolved "https://codeload.github.com/foundry-rs/forge-std/tar.gz/e8a047e3f40f13fa37af6fe14e6e06283d9a060e" +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== + +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@^11.0.0: version "11.1.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" @@ -1086,11 +2281,25 @@ fs-extra@^11.0.0: jsonfile "^6.0.1" universalify "^2.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.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.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -1127,13 +2336,25 @@ git-raw-commits@^2.0.11: split2 "^3.0.0" through2 "^4.0.0" -glob-parent@^5.1.2: +glob-parent@^5.1.2, 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.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: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -1183,7 +2404,7 @@ globby@10.0.0: merge2 "^1.2.3" slash "^3.0.0" -graceful-fs@^4.1.6, graceful-fs@^4.2.0: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -1193,6 +2414,60 @@ hard-rejection@^2.1.0: resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== +hardhat@^2.2.1: + version "2.19.1" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.1.tgz#5e09e8070ecfc6109ba9d3a4a117ec2b0643032a" + integrity sha512-bsWa63g1GB78ZyMN08WLhFElLPA+J+pShuKD1BFO2+88g3l+BL3R07vj9deIi9dMbssxgE714Gof1dBEDGqnCw== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "5.0.2" + "@nomicfoundation/ethereumjs-blockchain" "7.0.2" + "@nomicfoundation/ethereumjs-common" "4.0.2" + "@nomicfoundation/ethereumjs-evm" "2.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.2" + "@nomicfoundation/ethereumjs-statemanager" "2.0.2" + "@nomicfoundation/ethereumjs-trie" "6.0.2" + "@nomicfoundation/ethereumjs-tx" "5.0.2" + "@nomicfoundation/ethereumjs-util" "9.0.2" + "@nomicfoundation/ethereumjs-vm" "7.0.2" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.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" + 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-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1210,6 +2485,37 @@ has@^1.0.3: 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== + +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" + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -1222,6 +2528,25 @@ hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" +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" + +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" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -1237,13 +2562,18 @@ husky@>=8: resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== -iconv-lite@^0.4.24: +iconv-lite@0.4.24, 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" +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== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -1254,6 +2584,11 @@ ignore@^5.1.1, ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +immutable@^4.0.0-rc.12: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -1288,7 +2623,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@2, 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== @@ -1317,11 +2652,30 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" +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" + 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-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-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-core-module@^2.11.0, is-core-module@^2.5.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" @@ -1354,13 +2708,18 @@ is-fullwidth-code-point@^4.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== -is-glob@^4.0.1: +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-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -1371,7 +2730,7 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-plain-obj@2.1.0: +is-plain-obj@2.1.0, 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== @@ -1398,6 +2757,11 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" +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== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -1407,11 +2771,28 @@ isexe@^2.0.0: version "6.2.0-beta2" resolved "https://codeload.github.com/defi-wonderland/isolmate/tar.gz/59e18043c2450fef550f1744b3705ce9ebcaf1c8" +js-sdsl@^4.1.4: + version "4.4.2" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" + integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== + +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-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.0, 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" + js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" @@ -1420,13 +2801,6 @@ js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -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" - json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -1452,6 +2826,20 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +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" @@ -1466,11 +2854,48 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +keccak@^3.0.0, keccak@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + kind-of@^6.0.3: 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@^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" + +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@^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" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1522,6 +2947,14 @@ listr2@^5.0.7: through "^2.3.8" wrap-ansi "^7.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@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -1591,6 +3024,14 @@ lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17 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" + log-update@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" @@ -1601,6 +3042,13 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" +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@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1608,6 +3056,11 @@ lru-cache@^6.0.0: 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== + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -1623,6 +3076,34 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== +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" + +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== + meow@^8.0.0: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -1678,6 +3159,23 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +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" @@ -1713,16 +3211,70 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.6" +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" + +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.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: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ== +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== + +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -1733,6 +3285,16 @@ nice-try@^1.0.4: 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-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" + integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -1753,7 +3315,7 @@ normalize-package-data@^3.0.0: semver "^7.3.4" validate-npm-package-license "^3.0.1" -normalize-path@^3.0.0: +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== @@ -1777,6 +3339,11 @@ object-inspect@^1.12.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +obliterator@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" + integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1822,6 +3389,13 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +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@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -1836,6 +3410,13 @@ p-limit@^3.0.2: 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@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -1857,6 +3438,11 @@ p-map@^4.0.0: 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== + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -1887,6 +3473,11 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +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" @@ -1917,7 +3508,7 @@ path-key@^4.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== -path-parse@^1.0.7: +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== @@ -1927,7 +3518,18 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picomatch@^2.3.1: +pbkdf2@^3.0.17: + 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" + +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== @@ -1976,7 +3578,7 @@ q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== -queue-microtask@^1.2.2: +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== @@ -1986,6 +3588,23 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +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" + +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@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -2005,7 +3624,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -readable-stream@3, readable-stream@^3.0.0: +readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -2014,6 +3633,13 @@ readable-stream@3, readable-stream@^3.0.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +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" + redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -2032,7 +3658,7 @@ require-directory@^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@^2.0.2: +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== @@ -2059,6 +3685,13 @@ resolve-global@1.0.0, resolve-global@^1.0.0: dependencies: global-dirs "^0.1.1" +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: version "1.22.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" @@ -2101,11 +3734,40 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" +rimraf@^2.2.8: + 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.2.3: + 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-async@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +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" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -2113,6 +3775,11 @@ run-parallel@^1.1.9: 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== + rxjs@^6.4.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -2127,16 +3794,35 @@ rxjs@^7.8.0: dependencies: tslib "^2.1.0" -safe-buffer@~5.2.0: +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.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.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== + "safer-buffer@>= 2.1.2 < 3": 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: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + +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" + "semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.5.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -2168,6 +3854,31 @@ semver@^7.5.2: dependencies: lru-cache "^6.0.0" +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" + +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" @@ -2237,6 +3948,21 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.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" + solhint-plugin-defi-wonderland@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/solhint-plugin-defi-wonderland/-/solhint-plugin-defi-wonderland-1.1.0.tgz#6b82ee4da9fea1a4aeed4409915c3980f0f6b6a2" @@ -2308,6 +4034,19 @@ sort-package-json@1.53.1: is-plain-obj "2.1.0" sort-object-keys "^1.1.3" +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@^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.2.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" @@ -2346,6 +4085,18 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +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" + +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== + string-argv@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" @@ -2431,6 +4182,13 @@ strip-final-newline@^3.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== +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-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -2438,11 +4196,23 @@ strip-indent@^3.0.0: dependencies: min-indent "^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== + strip-json-comments@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== +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@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2505,7 +4275,7 @@ through2@^4.0.0: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -tmp@^0.0.33: +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== @@ -2519,6 +4289,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.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== + trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" @@ -2543,7 +4318,7 @@ ts-node@^10.8.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@^1.9.0: +tslib@^1.9.0, 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== @@ -2553,6 +4328,21 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +tsort@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" + integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== + +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@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -2575,6 +4365,11 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +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-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" @@ -2585,11 +4380,35 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== +undici@^5.14.0: + version "5.28.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.0.tgz#09f6aa4a6f34de8996eec585fe4ceebaa9ef3f36" + integrity sha512-gM12DkXhlAc5+/TPe60iy9P6ETgVfqTuRJ6aQ4w8RYu0MqKuXhaq3/b86GfzDQnNA3NUO6aUNdvevrKH59D0Nw== + dependencies: + "@fastify/busboy" "^2.0.0" + +uniswap@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/uniswap/-/uniswap-0.0.1.tgz#582ccde4b14ab5c2333d9aed429e921005936837" + integrity sha512-2ppSS+liwbH7kvnCnxoNSsFBIUdVJpwo6Q0IcDHdLfayFg/kOgIKt3Qq6WFi0SGYfU+bNTDIHxckapStnRvPVA== + dependencies: + hardhat "^2.2.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== +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== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -2602,6 +4421,11 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +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" @@ -2634,6 +4458,11 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +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@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -2664,11 +4493,26 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" +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@^7.4.6: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + 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== +yallist@^3.0.2: + 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" @@ -2679,7 +4523,12 @@ yaml@^2.2.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== -yargs-parser@^20.2.3: +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@^20.2.2, yargs-parser@^20.2.3: 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== @@ -2689,6 +4538,29 @@ yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +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@^17.0.0: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" From 5bedf21a9a2c46e8c3daf7730b3d5670204f307f Mon Sep 17 00:00:00 2001 From: deo Date: Mon, 27 Nov 2023 19:24:53 -0500 Subject: [PATCH 2/8] feat: swapper v2 --- solidity/test/unit/SwapperV2.t.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solidity/test/unit/SwapperV2.t.sol b/solidity/test/unit/SwapperV2.t.sol index 2251271e..ac14316f 100644 --- a/solidity/test/unit/SwapperV2.t.sol +++ b/solidity/test/unit/SwapperV2.t.sol @@ -145,3 +145,5 @@ contract SwapperV2Test is Test { } } } + +// From 7b3b566165963381ddacf44825b44f56f5128b71 Mon Sep 17 00:00:00 2001 From: deo Date: Mon, 27 Nov 2023 19:25:42 -0500 Subject: [PATCH 3/8] feat: swapper v2 --- solidity/test/unit/SwapperV2.t.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/solidity/test/unit/SwapperV2.t.sol b/solidity/test/unit/SwapperV2.t.sol index ac14316f..2251271e 100644 --- a/solidity/test/unit/SwapperV2.t.sol +++ b/solidity/test/unit/SwapperV2.t.sol @@ -145,5 +145,3 @@ contract SwapperV2Test is Test { } } } - -// From bcad6044fa215dc18e6e95fd18364739690fb30e Mon Sep 17 00:00:00 2001 From: deo Date: Tue, 28 Nov 2023 16:48:31 -0500 Subject: [PATCH 4/8] feat: v3 --- solidity/contracts/SwapperV3.sol | 93 ++++++++++++++++++++++++++++++ solidity/interfaces/ISwapperV3.sol | 24 ++++++++ 2 files changed, 117 insertions(+) create mode 100644 solidity/contracts/SwapperV3.sol create mode 100644 solidity/interfaces/ISwapperV3.sol diff --git a/solidity/contracts/SwapperV3.sol b/solidity/contracts/SwapperV3.sol new file mode 100644 index 00000000..cc0852de --- /dev/null +++ b/solidity/contracts/SwapperV3.sol @@ -0,0 +1,93 @@ +pragma solidity ^0.8.19; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; +import {IUniswapV2Router01} from '@uniswap/periphery/interfaces/IUniswapV2Router01.sol'; +import {IUniswapV2Pair} from '@uniswap/core/interfaces/IUniswapV2Pair.sol'; +import {ISwapperV3} from '../interfaces/ISwapperV3.sol'; + +/// @title Swapper contract V2 +/// @author 0xdeo +/// @notice Allows friends to pool their tokens and make a swap +/// @notice Routes swaps thru Uniswap +contract SwapperV3 is ISwapperV3, Ownable { + using SafeERC20 for IERC20; + + IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + IERC20 constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); + + IUniswapV2Router01 constant router = IUniswapV2Router01(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); + IUniswapV2Pair constant pair = IUniswapV2Pair(0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11); + + mapping(uint256 => Swap) public swaps; + uint256 swapId; + + constructor() Ownable(msg.sender) {} + + /// @notice Can only provide tokens when swap hasn't been done yet + /// @notice Cannot provide tokens if fromToken balance will exceed contract's toToken balance + /// @notice User's deposit gets recorded in latest epoch, and the swapId recording his deposit is then returned + function provide() public payable returns (uint256) { + swaps[swapId].balances[msg.sender] += msg.value; + + emit Provide(msg.sender, msg.value, swapId); + return swapId; + } + + /// @notice Initiates swap by sealing off further deposits and allowing withdrawals of toTokens, for that swapId's epoch + /// @notice Sends any deposited fromTokens to the owner of the contract who provided initial liquidity + function swap() public onlyOwner { + address[] memory _path = new address[](2); + _path[0] = address(WETH); + _path[1] = address(DAI); + (uint256 _reserve0, uint256 _reserve1,) = pair.getReserves(); + uint256 _amountOutMin; + uint256 _amountOut = DAI.balanceOf(address(this)); + uint256 _amountIn = address(this).balance; + + swaps[swapId].swapped = true; + swapId++; + + if (address(WETH) == pair.token0()) { + _amountOutMin = router.getAmountOut(address(this).balance, _reserve0, _reserve1); + } else { + _amountOutMin = router.getAmountOut(address(this).balance, _reserve1, _reserve0); + } + + // 1% slippage to prevent frontrunning + _amountOut = router.swapExactETHForTokens{value: address(this).balance}( + _amountOutMin * 99 / 100, _path, address(this), block.timestamp + )[1]; + + //_amountOut = DAI.balanceOf(address(this)) - _amountOut; + swaps[swapId - 1].totalOut = _amountOut; + swaps[swapId - 1].totalIn = _amountIn; + + emit Swapped(swapId - 1); + } + + /// @notice User must have nonzero balance + /// @notice If swap has been initiated, he receives toTokens in 1:1 ratio to his deposit + /// @notice Otherwise he is refunded the full amount he deposited. + /// @param _swapId ID designating epoch user's deposit belonged to + function withdraw(uint256 _swapId) public { + uint256 balance = swaps[_swapId].balances[msg.sender]; + swaps[_swapId].balances[msg.sender] = 0; + + if (balance == 0) { + revert ZeroBalance(); + } + + bool _refunded; + if (swaps[_swapId].swapped) { + balance = (balance * swaps[_swapId].totalOut) / swaps[_swapId].totalIn; + DAI.safeTransfer(msg.sender, balance); + } else { + _refunded = true; + payable(msg.sender).transfer(balance); + } + + emit Withdraw(msg.sender, balance, _swapId, _refunded); + } +} diff --git a/solidity/interfaces/ISwapperV3.sol b/solidity/interfaces/ISwapperV3.sol new file mode 100644 index 00000000..4ffaca14 --- /dev/null +++ b/solidity/interfaces/ISwapperV3.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.8.19; + +/// @title Swapper interface +/// @author 0xdeo +/// @notice Defines custom errors, function signatures and a struct for the swapper contract +interface ISwapperV3 { + function provide() external payable returns (uint256); + function swap() external; + function withdraw(uint256 _swapId) external; + + error ZeroBalance(); + + event Provide(address _depositor, uint256 _amount, uint256 _swapId); + event Swapped(uint256 _swapId); + event Withdraw(address _depositor, uint256 _amount, uint256 _swapId, bool _refunded); + event LiquidityAdded(uint256 _liquidity); + + struct Swap { + bool swapped; + uint256 totalIn; + uint256 totalOut; + mapping(address => uint256) balances; + } +} From 3372677cd7e3d450fc3c9a78b3c30358e382a6bf Mon Sep 17 00:00:00 2001 From: deo Date: Tue, 28 Nov 2023 17:16:16 -0500 Subject: [PATCH 5/8] feat: keep3r --- solidity/contracts/SwapperV3.sol | 34 +- solidity/interfaces/IKeep3rV2.sol | 715 +++++++++++++++++++++++++++++ solidity/interfaces/ISwapperV3.sol | 2 + 3 files changed, 748 insertions(+), 3 deletions(-) create mode 100644 solidity/interfaces/IKeep3rV2.sol diff --git a/solidity/contracts/SwapperV3.sol b/solidity/contracts/SwapperV3.sol index cc0852de..a8e0ec21 100644 --- a/solidity/contracts/SwapperV3.sol +++ b/solidity/contracts/SwapperV3.sol @@ -6,12 +6,13 @@ import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {IUniswapV2Router01} from '@uniswap/periphery/interfaces/IUniswapV2Router01.sol'; import {IUniswapV2Pair} from '@uniswap/core/interfaces/IUniswapV2Pair.sol'; import {ISwapperV3} from '../interfaces/ISwapperV3.sol'; +import {IKeep3rV2} from '../interfaces/IKeep3rV2.sol'; /// @title Swapper contract V2 /// @author 0xdeo /// @notice Allows friends to pool their tokens and make a swap /// @notice Routes swaps thru Uniswap -contract SwapperV3 is ISwapperV3, Ownable { +contract SwapperV3 is ISwapperV3 { using SafeERC20 for IERC20; IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); @@ -23,7 +24,16 @@ contract SwapperV3 is ISwapperV3, Ownable { mapping(uint256 => Swap) public swaps; uint256 swapId; - constructor() Ownable(msg.sender) {} + uint256 lastWorked; + address keep3r = 0xdc02981c9C062d48a9bD54adBf51b816623dcc6E; + + constructor() {} + + modifier validateAndPayKeeper(address _keeper) { + if (!IKeep3rV2(keep3r).isKeeper(_keeper)) revert KeeperNotValid(); + _; + IKeep3rV2(keep3r).worked(_keeper); + } /// @notice Can only provide tokens when swap hasn't been done yet /// @notice Cannot provide tokens if fromToken balance will exceed contract's toToken balance @@ -37,7 +47,7 @@ contract SwapperV3 is ISwapperV3, Ownable { /// @notice Initiates swap by sealing off further deposits and allowing withdrawals of toTokens, for that swapId's epoch /// @notice Sends any deposited fromTokens to the owner of the contract who provided initial liquidity - function swap() public onlyOwner { + function swap() public { address[] memory _path = new address[](2); _path[0] = address(WETH); _path[1] = address(DAI); @@ -90,4 +100,22 @@ contract SwapperV3 is ISwapperV3, Ownable { emit Withdraw(msg.sender, balance, _swapId, _refunded); } + + function work() external validateAndPayKeeper(msg.sender) { + if (!workable()) { + revert JobNotReady(); + } + + lastWorked = block.timestamp; + + swap(); + } + + function workable() public view returns (bool) { + if (block.timestamp >= lastWorked + 600) { + return true; + } + + return false; + } } diff --git a/solidity/interfaces/IKeep3rV2.sol b/solidity/interfaces/IKeep3rV2.sol new file mode 100644 index 00000000..485a610d --- /dev/null +++ b/solidity/interfaces/IKeep3rV2.sol @@ -0,0 +1,715 @@ +pragma solidity >=0.8.4 <0.9.0; + +interface IKeep3rV2 { + /// @notice Stores the tick information of the different liquidity pairs + struct TickCache { + int56 current; // Tracks the current tick + int56 difference; // Stores the difference between the current tick and the last tick + uint256 period; // Stores the period at which the last observation was made + } + + // Events + + /// @notice Emitted when the Keep3rHelper address is changed + /// @param _keep3rHelper The address of Keep3rHelper's contract + event Keep3rHelperChange(address _keep3rHelper); + + /// @notice Emitted when the Keep3rV1 address is changed + /// @param _keep3rV1 The address of Keep3rV1's contract + event Keep3rV1Change(address _keep3rV1); + + /// @notice Emitted when the Keep3rV1Proxy address is changed + /// @param _keep3rV1Proxy The address of Keep3rV1Proxy's contract + event Keep3rV1ProxyChange(address _keep3rV1Proxy); + + /// @notice Emitted when the KP3R-WETH pool address is changed + /// @param _kp3rWethPool The address of the KP3R-WETH pool + event Kp3rWethPoolChange(address _kp3rWethPool); + + /// @notice Emitted when bondTime is changed + /// @param _bondTime The new bondTime + event BondTimeChange(uint256 _bondTime); + + /// @notice Emitted when _liquidityMinimum is changed + /// @param _liquidityMinimum The new _liquidityMinimum + event LiquidityMinimumChange(uint256 _liquidityMinimum); + + /// @notice Emitted when _unbondTime is changed + /// @param _unbondTime The new _unbondTime + event UnbondTimeChange(uint256 _unbondTime); + + /// @notice Emitted when _rewardPeriodTime is changed + /// @param _rewardPeriodTime The new _rewardPeriodTime + event RewardPeriodTimeChange(uint256 _rewardPeriodTime); + + /// @notice Emitted when the inflationPeriod is changed + /// @param _inflationPeriod The new inflationPeriod + event InflationPeriodChange(uint256 _inflationPeriod); + + /// @notice Emitted when the fee is changed + /// @param _fee The new token credits fee + event FeeChange(uint256 _fee); + + /// @notice Emitted when a slasher is added + /// @param _slasher Address of the added slasher + event SlasherAdded(address _slasher); + + /// @notice Emitted when a slasher is removed + /// @param _slasher Address of the removed slasher + event SlasherRemoved(address _slasher); + + /// @notice Emitted when a disputer is added + /// @param _disputer Address of the added disputer + event DisputerAdded(address _disputer); + + /// @notice Emitted when a disputer is removed + /// @param _disputer Address of the removed disputer + event DisputerRemoved(address _disputer); + + /// @notice Emitted when the bonding process of a new keeper begins + /// @param _keeper The caller of Keep3rKeeperFundable#bond function + /// @param _bonding The asset the keeper has bonded + /// @param _amount The amount the keeper has bonded + event Bonding(address indexed _keeper, address indexed _bonding, uint256 _amount); + + /// @notice Emitted when a keeper or job begins the unbonding process to withdraw the funds + /// @param _keeperOrJob The keeper or job that began the unbonding process + /// @param _unbonding The liquidity pair or asset being unbonded + /// @param _amount The amount being unbonded + event Unbonding(address indexed _keeperOrJob, address indexed _unbonding, uint256 _amount); + + /// @notice Emitted when Keep3rKeeperFundable#activate is called + /// @param _keeper The keeper that has been activated + /// @param _bond The asset the keeper has bonded + /// @param _amount The amount of the asset the keeper has bonded + event Activation(address indexed _keeper, address indexed _bond, uint256 _amount); + + /// @notice Emitted when Keep3rKeeperFundable#withdraw is called + /// @param _keeper The caller of Keep3rKeeperFundable#withdraw function + /// @param _bond The asset to withdraw from the bonding pool + /// @param _amount The amount of funds withdrawn + event Withdrawal(address indexed _keeper, address indexed _bond, uint256 _amount); + + /// @notice Emitted when Keep3rKeeperDisputable#slash is called + /// @param _keeper The slashed keeper + /// @param _slasher The user that called Keep3rKeeperDisputable#slash + /// @param _amount The amount of credits slashed from the keeper + event KeeperSlash(address indexed _keeper, address indexed _slasher, uint256 _amount); + + /// @notice Emitted when Keep3rKeeperDisputable#revoke is called + /// @param _keeper The revoked keeper + /// @param _slasher The user that called Keep3rKeeperDisputable#revoke + event KeeperRevoke(address indexed _keeper, address indexed _slasher); + + /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called + /// @param _job The address of the job being credited + /// @param _token The address of the token being provided + /// @param _provider The user that calls the function + /// @param _amount The amount of credit being added to the job + event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount); + + /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called + /// @param _job The address of the job from which the credits are withdrawn + /// @param _token The credit being withdrawn from the job + /// @param _receiver The user that receives the tokens + /// @param _amount The amount of credit withdrawn + event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount); + + /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called + /// @param _liquidity The address of the liquidity pair being approved + event LiquidityApproval(address _liquidity); + + /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called + /// @param _liquidity The address of the liquidity pair being revoked + event LiquidityRevocation(address _liquidity); + + /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called + /// @param _job The address of the job to which liquidity will be added + /// @param _liquidity The address of the liquidity being added + /// @param _provider The user that calls the function + /// @param _amount The amount of liquidity being added + event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount); + + /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called + /// @param _job The address of the job of which liquidity will be withdrawn from + /// @param _liquidity The address of the liquidity being withdrawn + /// @param _receiver The receiver of the liquidity tokens + /// @param _amount The amount of liquidity being withdrawn from the job + event LiquidityWithdrawal( + address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount + ); + + /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called + /// @param _job The address of the job whose credits will be updated + /// @param _rewardedAt The time at which the job was last rewarded + /// @param _currentCredits The current credits of the job + /// @param _periodCredits The credits of the job for the current period + event LiquidityCreditsReward( + address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits + ); + + /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called + /// @param _job The address of the job whose credits will be updated + /// @param _rewardedAt The time at which the job was last rewarded + /// @param _currentCredits The current credits of the job + event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits); + + /// @notice Emitted when Keep3rJobManager#addJob is called + /// @param _job The address of the job to add + /// @param _jobOwner The job's owner + event JobAddition(address indexed _job, address indexed _jobOwner); + + /// @notice Emitted when a keeper is validated before a job + /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation + event KeeperValidation(uint256 _gasLeft); + + /// @notice Emitted when a keeper works a job + /// @param _credit The address of the asset in which the keeper is paid + /// @param _job The address of the job the keeper has worked + /// @param _keeper The address of the keeper that has worked the job + /// @param _amount The amount that has been paid out to the keeper in exchange for working the job + /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment + event KeeperWork( + address indexed _credit, address indexed _job, address indexed _keeper, uint256 _amount, uint256 _gasLeft + ); + + /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called + /// @param _job The address of the job proposed to have a change of owner + /// @param _owner The current owner of the job + /// @param _pendingOwner The new address proposed to be the owner of the job + event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner); + + /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called + /// @param _job The address of the job which the proposed owner will now own + /// @param _previousOwner The previous owner of the job + /// @param _newOwner The newowner of the job + event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner); + + /// @notice Emitted when Keep3rJobMigration#migrateJob function is called + /// @param _fromJob The address of the job that requests to migrate + /// @param _toJob The address at which the job requests to migrate + event JobMigrationRequested(address indexed _fromJob, address _toJob); + + /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called + /// @param _fromJob The address of the job that requested to migrate + /// @param _toJob The address at which the job had requested to migrate + event JobMigrationSuccessful(address _fromJob, address indexed _toJob); + + /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called + /// @param _job The address of the job from which the token will be slashed + /// @param _token The address of the token being slashed + /// @param _slasher The user that slashes the token + /// @param _amount The amount of the token being slashed + event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount); + + /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called + /// @param _job The address of the job from which the liquidity will be slashed + /// @param _liquidity The address of the liquidity being slashed + /// @param _slasher The user that slashes the liquidity + /// @param _amount The amount of the liquidity being slashed + event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount); + + /// @notice Emitted when a keeper or a job is disputed + /// @param _jobOrKeeper The address of the disputed keeper/job + /// @param _disputer The user that called the function and disputed the keeper + event Dispute(address indexed _jobOrKeeper, address indexed _disputer); + + /// @notice Emitted when a dispute is resolved + /// @param _jobOrKeeper The address of the disputed keeper/job + /// @param _resolver The user that called the function and resolved the dispute + event Resolve(address indexed _jobOrKeeper, address indexed _resolver); + + // Errors + + /// @notice Throws if the reward period is less than the minimum reward period time + error MinRewardPeriod(); + + /// @notice Throws if either a job or a keeper is disputed + error Disputed(); + + /// @notice Throws if there are no bonded assets + error BondsUnexistent(); + + /// @notice Throws if the time required to bond an asset has not passed yet + error BondsLocked(); + + /// @notice Throws if there are no bonds to withdraw + error UnbondsUnexistent(); + + /// @notice Throws if the time required to withdraw the bonds has not passed yet + error UnbondsLocked(); + + /// @notice Throws if the address is already a registered slasher + error SlasherExistent(); + + /// @notice Throws if caller is not a registered slasher + error SlasherUnexistent(); + + /// @notice Throws if the address is already a registered disputer + error DisputerExistent(); + + /// @notice Throws if caller is not a registered disputer + error DisputerUnexistent(); + + /// @notice Throws if the msg.sender is not a slasher or is not a part of governance + error OnlySlasher(); + + /// @notice Throws if the msg.sender is not a disputer or is not a part of governance + error OnlyDisputer(); + + /// @notice Throws when an address is passed as a job, but that address is not a job + error JobUnavailable(); + + /// @notice Throws when an action that requires an undisputed job is applied on a disputed job + error JobDisputed(); + + /// @notice Throws when the address that is trying to register as a job is already a job + error AlreadyAJob(); + + /// @notice Throws when the token is KP3R, as it should not be used for direct token payments + error TokenUnallowed(); + + /// @notice Throws when the token withdraw cooldown has not yet passed + error JobTokenCreditsLocked(); + + /// @notice Throws when the user tries to withdraw more tokens than it has + error InsufficientJobTokenCredits(); + + /// @notice Throws when trying to add a job that has already been added + error JobAlreadyAdded(); + + /// @notice Throws when the address that is trying to register as a keeper is already a keeper + error AlreadyAKeeper(); + + /// @notice Throws when the liquidity being approved has already been approved + error LiquidityPairApproved(); + + /// @notice Throws when the liquidity being removed has not been approved + error LiquidityPairUnexistent(); + + /// @notice Throws when trying to add liquidity to an unapproved pool + error LiquidityPairUnapproved(); + + /// @notice Throws when the job doesn't have the requested liquidity + error JobLiquidityUnexistent(); + + /// @notice Throws when trying to remove more liquidity than the job has + error JobLiquidityInsufficient(); + + /// @notice Throws when trying to add less liquidity than the minimum liquidity required + error JobLiquidityLessThanMin(); + + /// @notice Throws if a variable is assigned to the zero address + error ZeroAddress(); + + /// @notice Throws if the address claiming to be a job is not in the list of approved jobs + error JobUnapproved(); + + /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job + error InsufficientFunds(); + + /// @notice Throws when the caller of the function is not the job owner + error OnlyJobOwner(); + + /// @notice Throws when the caller of the function is not the pending job owner + error OnlyPendingJobOwner(); + + /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address + error JobMigrationImpossible(); + + /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping + error JobMigrationUnavailable(); + + /// @notice Throws when cooldown between migrations has not yet passed + error JobMigrationLocked(); + + /// @notice Throws when the token trying to be slashed doesn't exist + error JobTokenUnexistent(); + + /// @notice Throws when someone tries to slash more tokens than the job has + error JobTokenInsufficient(); + + /// @notice Throws when a job or keeper is already disputed + error AlreadyDisputed(); + + /// @notice Throws when a job or keeper is not disputed and someone tries to resolve the dispute + error NotDisputed(); + + // Variables + + /// @notice Address of Keep3rHelper's contract + /// @return _keep3rHelper The address of Keep3rHelper's contract + function keep3rHelper() external view returns (address _keep3rHelper); + + /// @notice Address of Keep3rV1's contract + /// @return _keep3rV1 The address of Keep3rV1's contract + function keep3rV1() external view returns (address _keep3rV1); + + /// @notice Address of Keep3rV1Proxy's contract + /// @return _keep3rV1Proxy The address of Keep3rV1Proxy's contract + function keep3rV1Proxy() external view returns (address _keep3rV1Proxy); + + /// @notice Address of the KP3R-WETH pool + /// @return _kp3rWethPool The address of KP3R-WETH pool + function kp3rWethPool() external view returns (address _kp3rWethPool); + + /// @notice The amount of time required to pass after a keeper has bonded assets for it to be able to activate + /// @return _days The required bondTime in days + function bondTime() external view returns (uint256 _days); + + /// @notice The amount of time required to pass before a keeper can unbond what he has bonded + /// @return _days The required unbondTime in days + function unbondTime() external view returns (uint256 _days); + + /// @notice The minimum amount of liquidity required to fund a job per liquidity + /// @return _amount The minimum amount of liquidity in KP3R + function liquidityMinimum() external view returns (uint256 _amount); + + /// @notice The amount of time between each scheduled credits reward given to a job + /// @return _days The reward period in days + function rewardPeriodTime() external view returns (uint256 _days); + + /// @notice The inflation period is the denominator used to regulate the emission of KP3R + /// @return _period The denominator used to regulate the emission of KP3R + function inflationPeriod() external view returns (uint256 _period); + + /// @notice The fee to be sent to governance when a user adds liquidity to a job + /// @return _amount The fee amount to be sent to governance when a user adds liquidity to a job + function fee() external view returns (uint256 _amount); + + // solhint-disable func-name-mixedcase + /// @notice The base that will be used to calculate the fee + /// @return _base The base that will be used to calculate the fee + function BASE() external view returns (uint256 _base); + + /// @notice The minimum rewardPeriodTime value to be set + /// @return _minPeriod The minimum reward period in seconds + function MIN_REWARD_PERIOD_TIME() external view returns (uint256 _minPeriod); + + /// @notice Maps an address to a boolean to determine whether the address is a slasher or not. + /// @return _isSlasher Whether the address is a slasher or not + function slashers(address _slasher) external view returns (bool _isSlasher); + + /// @notice Maps an address to a boolean to determine whether the address is a disputer or not. + /// @return _isDisputer Whether the address is a disputer or not + function disputers(address _disputer) external view returns (bool _isDisputer); + + /// @notice Tracks the total KP3R earnings of a keeper since it started working + /// @return _workCompleted Total KP3R earnings of a keeper since it started working + function workCompleted(address _keeper) external view returns (uint256 _workCompleted); + + /// @notice Tracks when a keeper was first registered + /// @return timestamp The time at which the keeper was first registered + function firstSeen(address _keeper) external view returns (uint256 timestamp); + + /// @notice Tracks if a keeper or job has a pending dispute + /// @return _disputed Whether a keeper or job has a pending dispute + function disputes(address _keeperOrJob) external view returns (bool _disputed); + + /// @notice Allows governance to create a dispute for a given keeper/job + /// @param _jobOrKeeper The address in dispute + function dispute(address _jobOrKeeper) external; + + /// @notice Allows governance to resolve a dispute on a keeper/job + /// @param _jobOrKeeper The address cleared + function resolve(address _jobOrKeeper) external; + + /// @notice Tracks how much a keeper has bonded of a certain token + /// @return _bonds Amount of a certain token that a keeper has bonded + function bonds(address _keeper, address _bond) external view returns (uint256 _bonds); + + /// @notice The current token credits available for a job + /// @return _amount The amount of token credits available for a job + function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount); + + /// @notice Tracks the amount of assets deposited in pending bonds + /// @return _pendingBonds Amount of a certain asset a keeper has unbonding + function pendingBonds(address _keeper, address _bonding) external view returns (uint256 _pendingBonds); + + /// @notice Tracks when a bonding for a keeper can be activated + /// @return _timestamp Time at which the bonding for a keeper can be activated + function canActivateAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp); + + /// @notice Tracks when keeper bonds are ready to be withdrawn + /// @return _timestamp Time at which the keeper bonds are ready to be withdrawn + function canWithdrawAfter(address _keeper, address _bonding) external view returns (uint256 _timestamp); + + /// @notice Tracks how much keeper bonds are to be withdrawn + /// @return _pendingUnbonds The amount of keeper bonds that are to be withdrawn + function pendingUnbonds(address _keeper, address _bonding) external view returns (uint256 _pendingUnbonds); + + /// @notice Checks whether the address has ever bonded an asset + /// @return _hasBonded Whether the address has ever bonded an asset + function hasBonded(address _keeper) external view returns (bool _hasBonded); + + /// @notice Last block where tokens were added to the job [job => token => timestamp] + /// @return _timestamp The last block where tokens were added to the job + function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp); + + // Methods + + /// @notice Add credit to a job to be paid out for work + /// @param _job The address of the job being credited + /// @param _token The address of the token being credited + /// @param _amount The amount of credit being added + function addTokenCreditsToJob(address _job, address _token, uint256 _amount) external; + + /// @notice Withdraw credit from a job + /// @param _job The address of the job from which the credits are withdrawn + /// @param _token The address of the token being withdrawn + /// @param _amount The amount of token to be withdrawn + /// @param _receiver The user that will receive tokens + function withdrawTokenCreditsFromJob(address _job, address _token, uint256 _amount, address _receiver) external; + + /// @notice Lists liquidity pairs + /// @return _list An array of addresses with all the approved liquidity pairs + function approvedLiquidities() external view returns (address[] memory _list); + + /// @notice Amount of liquidity in a specified job + /// @param _job The address of the job being checked + /// @param _liquidity The address of the liquidity we are checking + /// @return _amount Amount of liquidity in the specified job + function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount); + + /// @notice Last time the job was rewarded liquidity credits + /// @param _job The address of the job being checked + /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits + function rewardedAt(address _job) external view returns (uint256 _timestamp); + + /// @notice Last time the job was worked + /// @param _job The address of the job being checked + /// @return _timestamp Timestamp of the last time the job was worked + function workedAt(address _job) external view returns (uint256 _timestamp); + + /// @notice Maps the job to the owner of the job (job => user) + /// @return _owner The addres of the owner of the job + function jobOwner(address _job) external view returns (address _owner); + + /// @notice Maps the owner of the job to its pending owner (job => user) + /// @return _pendingOwner The address of the pending owner of the job + function jobPendingOwner(address _job) external view returns (address _pendingOwner); + + /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to + /// @return _toJob The address to which the job has requested to migrate to + function pendingJobMigrations(address _fromJob) external view returns (address _toJob); + + // Methods + + /// @notice Sets the Keep3rHelper address + /// @param _keep3rHelper The Keep3rHelper address + function setKeep3rHelper(address _keep3rHelper) external; + + /// @notice Sets the Keep3rV1 address + /// @param _keep3rV1 The Keep3rV1 address + function setKeep3rV1(address _keep3rV1) external; + + /// @notice Sets the Keep3rV1Proxy address + /// @param _keep3rV1Proxy The Keep3rV1Proxy address + function setKeep3rV1Proxy(address _keep3rV1Proxy) external; + + /// @notice Sets the KP3R-WETH pool address + /// @param _kp3rWethPool The KP3R-WETH pool address + function setKp3rWethPool(address _kp3rWethPool) external; + + /// @notice Sets the bond time required to activate as a keeper + /// @param _bond The new bond time + function setBondTime(uint256 _bond) external; + + /// @notice Sets the unbond time required unbond what has been bonded + /// @param _unbond The new unbond time + function setUnbondTime(uint256 _unbond) external; + + /// @notice Sets the minimum amount of liquidity required to fund a job + /// @param _liquidityMinimum The new minimum amount of liquidity + function setLiquidityMinimum(uint256 _liquidityMinimum) external; + + /// @notice Sets the time required to pass between rewards for jobs + /// @param _rewardPeriodTime The new amount of time required to pass between rewards + function setRewardPeriodTime(uint256 _rewardPeriodTime) external; + + /// @notice Sets the new inflation period + /// @param _inflationPeriod The new inflation period + function setInflationPeriod(uint256 _inflationPeriod) external; + + /// @notice Sets the new fee + /// @param _fee The new fee + function setFee(uint256 _fee) external; + + /// @notice Registers a slasher by updating the slashers mapping + function addSlasher(address _slasher) external; + + /// @notice Removes a slasher by updating the slashers mapping + function removeSlasher(address _slasher) external; + + /// @notice Registers a disputer by updating the disputers mapping + function addDisputer(address _disputer) external; + + /// @notice Removes a disputer by updating the disputers mapping + function removeDisputer(address _disputer) external; + + /// @notice Lists all jobs + /// @return _jobList Array with all the jobs in _jobs + function jobs() external view returns (address[] memory _jobList); + + /// @notice Lists all keepers + /// @return _keeperList Array with all the jobs in keepers + function keepers() external view returns (address[] memory _keeperList); + + /// @notice Beginning of the bonding process + /// @param _bonding The asset being bound + /// @param _amount The amount of bonding asset being bound + function bond(address _bonding, uint256 _amount) external; + + /// @notice Beginning of the unbonding process + /// @param _bonding The asset being unbound + /// @param _amount Allows for partial unbonding + function unbond(address _bonding, uint256 _amount) external; + + /// @notice End of the bonding process after bonding time has passed + /// @param _bonding The asset being activated as bond collateral + function activate(address _bonding) external; + + /// @notice Withdraw funds after unbonding has finished + /// @param _bonding The asset to withdraw from the bonding pool + function withdraw(address _bonding) external; + + /// @notice Allows governance to slash a keeper based on a dispute + /// @param _keeper The address being slashed + /// @param _bonded The asset being slashed + /// @param _amount The amount being slashed + function slash(address _keeper, address _bonded, uint256 _amount) external; + + /// @notice Blacklists a keeper from participating in the network + /// @param _keeper The address being slashed + function revoke(address _keeper) external; + + /// @notice Allows any caller to add a new job + /// @param _job Address of the contract for which work should be performed + function addJob(address _job) external; + + /// @notice Returns the liquidity credits of a given job + /// @param _job The address of the job of which we want to know the liquidity credits + /// @return _amount The liquidity credits of a given job + function jobLiquidityCredits(address _job) external view returns (uint256 _amount); + + /// @notice Returns the credits of a given job for the current period + /// @param _job The address of the job of which we want to know the period credits + /// @return _amount The credits the given job has at the current period + function jobPeriodCredits(address _job) external view returns (uint256 _amount); + + /// @notice Calculates the total credits of a given job + /// @param _job The address of the job of which we want to know the total credits + /// @return _amount The total credits of the given job + function totalJobCredits(address _job) external view returns (uint256 _amount); + + /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount + /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod + /// @param _liquidity The liquidity to provide + /// @param _amount The amount of liquidity to provide + /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity + function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits); + + /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information + /// @param _liquidity The liquidity pair being observed + /// @return _tickCache The updated TickCache + function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache); + + /// @notice Gifts liquidity credits to the specified job + /// @param _job The address of the job being credited + /// @param _amount The amount of liquidity credits to gift + function forceLiquidityCreditsToJob(address _job, uint256 _amount) external; + + /// @notice Approve a liquidity pair for being accepted in future + /// @param _liquidity The address of the liquidity accepted + function approveLiquidity(address _liquidity) external; + + /// @notice Revoke a liquidity pair from being accepted in future + /// @param _liquidity The liquidity no longer accepted + function revokeLiquidity(address _liquidity) external; + + /// @notice Allows anyone to fund a job with liquidity + /// @param _job The address of the job to assign liquidity to + /// @param _liquidity The liquidity being added + /// @param _amount The amount of liquidity tokens to add + function addLiquidityToJob(address _job, address _liquidity, uint256 _amount) external; + + /// @notice Unbond liquidity for a job + /// @dev Can only be called by the job's owner + /// @param _job The address of the job being unbound from + /// @param _liquidity The liquidity being unbound + /// @param _amount The amount of liquidity being removed + function unbondLiquidityFromJob(address _job, address _liquidity, uint256 _amount) external; + + /// @notice Withdraw liquidity from a job + /// @param _job The address of the job being withdrawn from + /// @param _liquidity The liquidity being withdrawn + /// @param _receiver The address that will receive the withdrawn liquidity + function withdrawLiquidityFromJob(address _job, address _liquidity, address _receiver) external; + + /// @notice Confirms if the current keeper is registered, can be used for general (non critical) functions + /// @param _keeper The keeper being investigated + /// @return _isKeeper Whether the address passed as a parameter is a keeper or not + function isKeeper(address _keeper) external returns (bool _isKeeper); + + /// @notice Confirms if the current keeper is registered and has a minimum bond of any asset. Should be used for protected functions + /// @param _keeper The keeper to check + /// @param _bond The bond token being evaluated + /// @param _minBond The minimum amount of bonded tokens + /// @param _earned The minimum funds earned in the keepers lifetime + /// @param _age The minimum keeper age required + /// @return _isBondedKeeper Whether the `_keeper` meets the given requirements + function isBondedKeeper( + address _keeper, + address _bond, + uint256 _minBond, + uint256 _earned, + uint256 _age + ) external returns (bool _isBondedKeeper); + + /// @notice Implemented by jobs to show that a keeper performed work + /// @dev Automatically calculates the payment for the keeper + /// @param _keeper Address of the keeper that performed the work + function worked(address _keeper) external; + + /// @notice Implemented by jobs to show that a keeper performed work + /// @dev Pays the keeper that performs the work with KP3R + /// @param _keeper Address of the keeper that performed the work + /// @param _payment The reward that should be allocated for the job + function bondedPayment(address _keeper, uint256 _payment) external; + + /// @notice Implemented by jobs to show that a keeper performed work + /// @dev Pays the keeper that performs the work with a specific token + /// @param _token The asset being awarded to the keeper + /// @param _keeper Address of the keeper that performed the work + /// @param _amount The reward that should be allocated + function directTokenPayment(address _token, address _keeper, uint256 _amount) external; + + /// @notice Proposes a new address to be the owner of the job + function changeJobOwnership(address _job, address _newOwner) external; + + /// @notice The proposed address accepts to be the owner of the job + function acceptJobOwnership(address _job) external; + + /// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping + /// @param _fromJob The address of the job that is requesting to migrate + /// @param _toJob The address at which the job is requesting to migrate + function migrateJob(address _fromJob, address _toJob) external; + + /// @notice Completes the migration process for a job + /// @dev Unbond/withdraw process doesn't get migrated + /// @param _fromJob The address of the job that requested to migrate + /// @param _toJob The address to which the job wants to migrate to + function acceptJobMigration(address _fromJob, address _toJob) external; + + /// @notice Allows governance or slasher to slash a job specific token + /// @param _job The address of the job from which the token will be slashed + /// @param _token The address of the token that will be slashed + /// @param _amount The amount of the token that will be slashed + function slashTokenFromJob(address _job, address _token, uint256 _amount) external; + + /// @notice Allows governance or a slasher to slash liquidity from a job + /// @param _job The address being slashed + /// @param _liquidity The address of the liquidity that will be slashed + /// @param _amount The amount of liquidity that will be slashed + function slashLiquidityFromJob(address _job, address _liquidity, uint256 _amount) external; +} diff --git a/solidity/interfaces/ISwapperV3.sol b/solidity/interfaces/ISwapperV3.sol index 4ffaca14..4a00b158 100644 --- a/solidity/interfaces/ISwapperV3.sol +++ b/solidity/interfaces/ISwapperV3.sol @@ -9,6 +9,8 @@ interface ISwapperV3 { function withdraw(uint256 _swapId) external; error ZeroBalance(); + error KeeperNotValid(); + error JobNotReady(); event Provide(address _depositor, uint256 _amount, uint256 _swapId); event Swapped(uint256 _swapId); From 9cba32f1e2cdac841255c9f91d019fee2a6926b4 Mon Sep 17 00:00:00 2001 From: deo Date: Wed, 29 Nov 2023 13:02:21 -0500 Subject: [PATCH 6/8] feat: job functionality tested --- solidity/contracts/SwapperV3.sol | 2 +- solidity/test/unit/SwapperV3.t.sol | 179 +++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 solidity/test/unit/SwapperV3.t.sol diff --git a/solidity/contracts/SwapperV3.sol b/solidity/contracts/SwapperV3.sol index a8e0ec21..380c2841 100644 --- a/solidity/contracts/SwapperV3.sol +++ b/solidity/contracts/SwapperV3.sol @@ -32,7 +32,7 @@ contract SwapperV3 is ISwapperV3 { modifier validateAndPayKeeper(address _keeper) { if (!IKeep3rV2(keep3r).isKeeper(_keeper)) revert KeeperNotValid(); _; - IKeep3rV2(keep3r).worked(_keeper); + IKeep3rV2(keep3r).directTokenPayment(address(WETH), _keeper, 1e17); } /// @notice Can only provide tokens when swap hasn't been done yet diff --git a/solidity/test/unit/SwapperV3.t.sol b/solidity/test/unit/SwapperV3.t.sol new file mode 100644 index 00000000..e842e4ec --- /dev/null +++ b/solidity/test/unit/SwapperV3.t.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import {Test, console2} from 'forge-std/Test.sol'; +import {SwapperV3} from '../../contracts/SwapperV3.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IKeep3rV2} from '../../interfaces/IKeep3rV2.sol'; + +error InsufficientLiquidity(); +error ZeroBalance(); + +contract SwapperV3Test is Test { + SwapperV3 public swapper; + IKeep3rV2 keep3r = IKeep3rV2(0xdc02981c9C062d48a9bD54adBf51b816623dcc6E); + IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + + IERC20 constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); + + address alice = makeAddr('alice'); + address bob = makeAddr('bob'); + address eve = makeAddr('eve'); + + address keeper = 0x9429cd74A3984396f3117d51cde46ea8e0e21487; + + uint256 constant LIQUIDITY = 100e18; + + function setUp() public { + vm.createSelectFork(vm.envString('MAINNET_RPC')); + + swapper = new SwapperV3(); + + deal(address(WETH), address(this), LIQUIDITY); + + deal(alice, 1e18); + deal(bob, 2e18); + deal(eve, 10e18); + deal(keeper, 10e18); + + WETH.approve(address(keep3r), LIQUIDITY); + keep3r.addJob(address(swapper)); + keep3r.addTokenCreditsToJob(address(swapper), address(WETH), LIQUIDITY); + } + + //Basic check that tokens are correctly provided to the swapper when providing + function testProvide() public { + vm.startPrank(alice); + swapper.provide{value: 1e18}(); + + assertEq(address(swapper).balance, 1e18); + } + + // User should be able to get a refund for any deposited tokens not yet swapped + function testRefund() public { + vm.startPrank(alice); + uint256 _swapId = swapper.provide{value: 1e18}(); + swapper.withdraw(_swapId); + + assertEq(alice.balance, 1e18); + } + + // Alice should be allowed to swap her tokens and receive the correct amount of toTokens + // Contract deployer receives all excess tokens + function testSwap() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertEq(DAI.balanceOf(address(this)), 0); + } + + // Testing swaps over multiple epochs + function testMultipleEpochs() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + vm.prank(bob); + _swapId = swapper.provide{value: 1e18}(); + + swapper.swap(); + + vm.prank(bob); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertGt(DAI.balanceOf(bob), 0); + assertEq(DAI.balanceOf(address(this)), 0); + } + + // Testing multiple swaps over same epoch + // alice and bob do the swap and get toTokens + // eve gets a refund + function testMultipleSwaps() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + vm.prank(bob); + + _swapId = swapper.provide{value: 1e18}(); + + vm.prank(eve); + + _swapId = swapper.provide{value: 1e18}(); + + vm.prank(eve); + swapper.withdraw(_swapId); + + swapper.swap(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + vm.prank(bob); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertGt(DAI.balanceOf(bob), 0); + assertEq(eve.balance, 10e18); + assertEq(DAI.balanceOf(address(this)), 0); + } + + function testFuzz_swap(uint256 _amount, bool swap) public { + _amount = bound(_amount, 1, 1e21); + deal(alice, _amount); + + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: _amount}(); + + if (swap) { + swapper.swap(); + } + + vm.prank(alice); + swapper.withdraw(_swapId); + + if (swap) { + assertEq(DAI.balanceOf(address(this)), 0); + assertGt(DAI.balanceOf(alice), 0); + } else { + assertEq(alice.balance, _amount); + } + } + + function testCredits() public { + assertEq(keep3r.jobTokenCredits(address(swapper), address(WETH)), LIQUIDITY * 997 / 1000); + } + + function testJob() public { + vm.prank(alice); + + uint256 _swapId = swapper.provide{value: 1e18}(); + + vm.prank(keeper); + swapper.work(); + + vm.prank(alice); + swapper.withdraw(_swapId); + + assertGt(DAI.balanceOf(alice), 0); + assertEq(DAI.balanceOf(address(this)), 0); + assertEq(swapper.workable(), false); + + vm.warp(block.timestamp + 600); + assertEq(swapper.workable(), true); + } +} From 65faa755e322ab24bea383e9a6a470e765e33d32 Mon Sep 17 00:00:00 2001 From: deo Date: Thu, 30 Nov 2023 18:23:32 -0500 Subject: [PATCH 7/8] fix: shaito suggested fixes implemented, cleaned up repo for future projects --- solidity/contracts/Swapper/Keeper.sol | 37 +++++++++++ solidity/contracts/{ => Swapper}/Swapper.sol | 2 +- .../contracts/{ => Swapper}/SwapperV2.sol | 2 +- .../contracts/{ => Swapper}/SwapperV3.sol | 66 +++++++++---------- .../interfaces/{ => Swapper}/IKeep3rV2.sol | 0 .../interfaces/{ => Swapper}/ISwapper.sol | 0 .../interfaces/{ => Swapper}/ISwapperV2.sol | 0 .../interfaces/{ => Swapper}/ISwapperV3.sol | 3 +- solidity/interfaces/Swapper/IWETH.sol | 7 ++ .../test/unit/{ => Swapper}/Swapper.t.sol | 2 +- .../test/unit/{ => Swapper}/SwapperV2.t.sol | 2 +- .../test/unit/{ => Swapper}/SwapperV3.t.sol | 4 +- 12 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 solidity/contracts/Swapper/Keeper.sol rename solidity/contracts/{ => Swapper}/Swapper.sol (97%) rename solidity/contracts/{ => Swapper}/SwapperV2.sol (98%) rename solidity/contracts/{ => Swapper}/SwapperV3.sol (70%) rename solidity/interfaces/{ => Swapper}/IKeep3rV2.sol (100%) rename solidity/interfaces/{ => Swapper}/ISwapper.sol (100%) rename solidity/interfaces/{ => Swapper}/ISwapperV2.sol (100%) rename solidity/interfaces/{ => Swapper}/ISwapperV3.sol (93%) create mode 100644 solidity/interfaces/Swapper/IWETH.sol rename solidity/test/unit/{ => Swapper}/Swapper.t.sol (98%) rename solidity/test/unit/{ => Swapper}/SwapperV2.t.sol (98%) rename solidity/test/unit/{ => Swapper}/SwapperV3.t.sol (96%) diff --git a/solidity/contracts/Swapper/Keeper.sol b/solidity/contracts/Swapper/Keeper.sol new file mode 100644 index 00000000..00883826 --- /dev/null +++ b/solidity/contracts/Swapper/Keeper.sol @@ -0,0 +1,37 @@ +pragma solidity ^0.8.19; + +import {IKeep3rV2} from '../../interfaces/Swapper/IKeep3rV2.sol'; +import {IWETH} from '../../interfaces/Swapper/IWETH.sol'; + +contract Keeper { + error KeeperNotValid(); + error JobNotReady(); + + uint256 lastWorked; + address keep3r = 0xdc02981c9C062d48a9bD54adBf51b816623dcc6E; + uint256 constant TEN_MINUTES = 600; + + IWETH constant WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + + modifier validateAndPayKeeper(address _keeper) { + if (!IKeep3rV2(keep3r).isKeeper(_keeper)) revert KeeperNotValid(); + _; + IKeep3rV2(keep3r).directTokenPayment(address(WETH), _keeper, 1e17); + } + + function work() external validateAndPayKeeper(msg.sender) { + if (!workable()) { + revert JobNotReady(); + } + + lastWorked = block.timestamp; + + swap(); + } + + function workable() public view returns (bool _workable) { + return block.timestamp >= lastWorked + TEN_MINUTES; + } + + function swap() public virtual {} +} diff --git a/solidity/contracts/Swapper.sol b/solidity/contracts/Swapper/Swapper.sol similarity index 97% rename from solidity/contracts/Swapper.sol rename to solidity/contracts/Swapper/Swapper.sol index bb64d393..91b60338 100644 --- a/solidity/contracts/Swapper.sol +++ b/solidity/contracts/Swapper/Swapper.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; -import {ISwapper} from '../interfaces/ISwapper.sol'; +import {ISwapper} from '../../interfaces/Swapper/ISwapper.sol'; /// @title Swapper contract /// @author 0xdeo diff --git a/solidity/contracts/SwapperV2.sol b/solidity/contracts/Swapper/SwapperV2.sol similarity index 98% rename from solidity/contracts/SwapperV2.sol rename to solidity/contracts/Swapper/SwapperV2.sol index 394dedb4..e2c93029 100644 --- a/solidity/contracts/SwapperV2.sol +++ b/solidity/contracts/Swapper/SwapperV2.sol @@ -5,7 +5,7 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {IUniswapV2Router01} from '@uniswap/periphery/interfaces/IUniswapV2Router01.sol'; import {IUniswapV2Pair} from '@uniswap/core/interfaces/IUniswapV2Pair.sol'; -import {ISwapperV2} from '../interfaces/ISwapperV2.sol'; +import {ISwapperV2} from '../../interfaces/Swapper/ISwapperV2.sol'; /// @title Swapper contract V2 /// @author 0xdeo diff --git a/solidity/contracts/SwapperV3.sol b/solidity/contracts/Swapper/SwapperV3.sol similarity index 70% rename from solidity/contracts/SwapperV3.sol rename to solidity/contracts/Swapper/SwapperV3.sol index 380c2841..5cf755d5 100644 --- a/solidity/contracts/SwapperV3.sol +++ b/solidity/contracts/Swapper/SwapperV3.sol @@ -5,41 +5,44 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {IUniswapV2Router01} from '@uniswap/periphery/interfaces/IUniswapV2Router01.sol'; import {IUniswapV2Pair} from '@uniswap/core/interfaces/IUniswapV2Pair.sol'; -import {ISwapperV3} from '../interfaces/ISwapperV3.sol'; -import {IKeep3rV2} from '../interfaces/IKeep3rV2.sol'; +import {ISwapperV3} from '../../interfaces/Swapper/ISwapperV3.sol'; +import {Keeper} from './Keeper.sol'; /// @title Swapper contract V2 /// @author 0xdeo /// @notice Allows friends to pool their tokens and make a swap /// @notice Routes swaps thru Uniswap -contract SwapperV3 is ISwapperV3 { +contract SwapperV3 is ISwapperV3, Keeper { using SafeERC20 for IERC20; - IERC20 constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); IERC20 constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); IUniswapV2Router01 constant router = IUniswapV2Router01(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); IUniswapV2Pair constant pair = IUniswapV2Pair(0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11); - mapping(uint256 => Swap) public swaps; + mapping(uint256 _swapId => Swap _swapData) public swaps; uint256 swapId; - uint256 lastWorked; - address keep3r = 0xdc02981c9C062d48a9bD54adBf51b816623dcc6E; - constructor() {} - modifier validateAndPayKeeper(address _keeper) { - if (!IKeep3rV2(keep3r).isKeeper(_keeper)) revert KeeperNotValid(); - _; - IKeep3rV2(keep3r).directTokenPayment(address(WETH), _keeper, 1e17); + /// @notice Can provide ETH when swap hasn't been done yet + /// @notice Cannot provide tokens if fromToken balance will exceed contract's toToken balance + /// @notice User's deposit gets recorded in latest epoch, and the swapId recording his deposit is then returned + function provide() public payable returns (uint256 _swapId) { + swaps[swapId].balances[msg.sender] += msg.value; + + emit Provide(msg.sender, msg.value, swapId); + return swapId; } - /// @notice Can only provide tokens when swap hasn't been done yet + /// @notice Can provide WETH when swap hasn't been done yet /// @notice Cannot provide tokens if fromToken balance will exceed contract's toToken balance /// @notice User's deposit gets recorded in latest epoch, and the swapId recording his deposit is then returned - function provide() public payable returns (uint256) { - swaps[swapId].balances[msg.sender] += msg.value; + /// @param _deposit amount of WETH the user deposited + function provide(uint256 _deposit) public payable returns (uint256 _swapId) { + swaps[swapId].balances[msg.sender] += _deposit; + + WETH.transferFrom(msg.sender, address(this), _deposit); emit Provide(msg.sender, msg.value, swapId); return swapId; @@ -47,17 +50,17 @@ contract SwapperV3 is ISwapperV3 { /// @notice Initiates swap by sealing off further deposits and allowing withdrawals of toTokens, for that swapId's epoch /// @notice Sends any deposited fromTokens to the owner of the contract who provided initial liquidity - function swap() public { + function swap() public virtual override(ISwapperV3, Keeper) { address[] memory _path = new address[](2); _path[0] = address(WETH); _path[1] = address(DAI); (uint256 _reserve0, uint256 _reserve1,) = pair.getReserves(); uint256 _amountOutMin; - uint256 _amountOut = DAI.balanceOf(address(this)); + uint256 _amountOut; uint256 _amountIn = address(this).balance; swaps[swapId].swapped = true; - swapId++; + ++swapId; if (address(WETH) == pair.token0()) { _amountOutMin = router.getAmountOut(address(this).balance, _reserve0, _reserve1); @@ -65,6 +68,10 @@ contract SwapperV3 is ISwapperV3 { _amountOutMin = router.getAmountOut(address(this).balance, _reserve1, _reserve0); } + if (WETH.balanceOf(address(this)) != 0) { + WETH.withdraw(WETH.balanceOf(address(this))); + } + // 1% slippage to prevent frontrunning _amountOut = router.swapExactETHForTokens{value: address(this).balance}( _amountOutMin * 99 / 100, _path, address(this), block.timestamp @@ -95,27 +102,18 @@ contract SwapperV3 is ISwapperV3 { DAI.safeTransfer(msg.sender, balance); } else { _refunded = true; - payable(msg.sender).transfer(balance); - } - emit Withdraw(msg.sender, balance, _swapId, _refunded); - } + (bool _success,) = payable(msg.sender).call{value: balance}(''); - function work() external validateAndPayKeeper(msg.sender) { - if (!workable()) { - revert JobNotReady(); + if (!_success) { + revert RefundFailed(); + } } - lastWorked = block.timestamp; - - swap(); + emit Withdraw(msg.sender, balance, _swapId, _refunded); } - function workable() public view returns (bool) { - if (block.timestamp >= lastWorked + 600) { - return true; - } - - return false; + receive() external payable { + provide(); } } diff --git a/solidity/interfaces/IKeep3rV2.sol b/solidity/interfaces/Swapper/IKeep3rV2.sol similarity index 100% rename from solidity/interfaces/IKeep3rV2.sol rename to solidity/interfaces/Swapper/IKeep3rV2.sol diff --git a/solidity/interfaces/ISwapper.sol b/solidity/interfaces/Swapper/ISwapper.sol similarity index 100% rename from solidity/interfaces/ISwapper.sol rename to solidity/interfaces/Swapper/ISwapper.sol diff --git a/solidity/interfaces/ISwapperV2.sol b/solidity/interfaces/Swapper/ISwapperV2.sol similarity index 100% rename from solidity/interfaces/ISwapperV2.sol rename to solidity/interfaces/Swapper/ISwapperV2.sol diff --git a/solidity/interfaces/ISwapperV3.sol b/solidity/interfaces/Swapper/ISwapperV3.sol similarity index 93% rename from solidity/interfaces/ISwapperV3.sol rename to solidity/interfaces/Swapper/ISwapperV3.sol index 4a00b158..7f4892aa 100644 --- a/solidity/interfaces/ISwapperV3.sol +++ b/solidity/interfaces/Swapper/ISwapperV3.sol @@ -9,8 +9,7 @@ interface ISwapperV3 { function withdraw(uint256 _swapId) external; error ZeroBalance(); - error KeeperNotValid(); - error JobNotReady(); + error RefundFailed(); event Provide(address _depositor, uint256 _amount, uint256 _swapId); event Swapped(uint256 _swapId); diff --git a/solidity/interfaces/Swapper/IWETH.sol b/solidity/interfaces/Swapper/IWETH.sol new file mode 100644 index 00000000..f0f2ff3b --- /dev/null +++ b/solidity/interfaces/Swapper/IWETH.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.8.19; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +interface IWETH is IERC20 { + function withdraw(uint256 wad) external; +} diff --git a/solidity/test/unit/Swapper.t.sol b/solidity/test/unit/Swapper/Swapper.t.sol similarity index 98% rename from solidity/test/unit/Swapper.t.sol rename to solidity/test/unit/Swapper/Swapper.t.sol index 64f94f8f..63760972 100644 --- a/solidity/test/unit/Swapper.t.sol +++ b/solidity/test/unit/Swapper/Swapper.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import {Test, console2} from 'forge-std/Test.sol'; -import {Swapper} from '../../contracts/Swapper.sol'; +import {Swapper} from '../../../contracts/Swapper/Swapper.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; error InsufficientLiquidity(); diff --git a/solidity/test/unit/SwapperV2.t.sol b/solidity/test/unit/Swapper/SwapperV2.t.sol similarity index 98% rename from solidity/test/unit/SwapperV2.t.sol rename to solidity/test/unit/Swapper/SwapperV2.t.sol index 2251271e..eb1a6ccc 100644 --- a/solidity/test/unit/SwapperV2.t.sol +++ b/solidity/test/unit/Swapper/SwapperV2.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import {Test, console2} from 'forge-std/Test.sol'; -import {SwapperV2} from '../../contracts/SwapperV2.sol'; +import {SwapperV2} from '../../../contracts/Swapper/SwapperV2.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; error InsufficientLiquidity(); diff --git a/solidity/test/unit/SwapperV3.t.sol b/solidity/test/unit/Swapper/SwapperV3.t.sol similarity index 96% rename from solidity/test/unit/SwapperV3.t.sol rename to solidity/test/unit/Swapper/SwapperV3.t.sol index e842e4ec..68687efa 100644 --- a/solidity/test/unit/SwapperV3.t.sol +++ b/solidity/test/unit/Swapper/SwapperV3.t.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.19; import {Test, console2} from 'forge-std/Test.sol'; -import {SwapperV3} from '../../contracts/SwapperV3.sol'; +import {SwapperV3} from '../../../contracts/Swapper/SwapperV3.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IKeep3rV2} from '../../interfaces/IKeep3rV2.sol'; +import {IKeep3rV2} from '../../../interfaces/Swapper/IKeep3rV2.sol'; error InsufficientLiquidity(); error ZeroBalance(); From 6c26f88839875aa9fb40697f83e2980854caab0a Mon Sep 17 00:00:00 2001 From: deo Date: Wed, 20 Dec 2023 01:34:26 -0500 Subject: [PATCH 8/8] feat: finished oracle project' --- solidity/contracts/Oracle/Oracle.sol | 73 +++++++++++ solidity/contracts/Swapper/SwapperV3.sol | 1 - solidity/interfaces/Oracle/IOracle.sol | 10 ++ solidity/interfaces/Oracle/IWrapper.sol | 5 + .../test/unit/Oracle/Mocks/1inchWrapper.sol | 28 +++++ .../unit/Oracle/Mocks/ChainlinkWrapper.sol | 49 ++++++++ .../test/unit/Oracle/Mocks/CurveWrapper.sol | 48 ++++++++ .../unit/Oracle/Mocks/Interfaces/I1inch.sol | 13 ++ .../Oracle/Mocks/Interfaces/ICurveFactory.sol | 5 + .../Oracle/Mocks/Interfaces/IStableSwap.sol | 6 + .../test/unit/Oracle/Mocks/SushiWrapper.sol | 41 +++++++ .../unit/Oracle/Mocks/UniswapV3Wrapper.sol | 113 ++++++++++++++++++ .../test/unit/Oracle/Mocks/UniswapWrapper.sol | 57 +++++++++ solidity/test/unit/Oracle/Oracle.t.sol | 29 +++++ 14 files changed, 477 insertions(+), 1 deletion(-) create mode 100644 solidity/contracts/Oracle/Oracle.sol create mode 100644 solidity/interfaces/Oracle/IOracle.sol create mode 100644 solidity/interfaces/Oracle/IWrapper.sol create mode 100644 solidity/test/unit/Oracle/Mocks/1inchWrapper.sol create mode 100644 solidity/test/unit/Oracle/Mocks/ChainlinkWrapper.sol create mode 100644 solidity/test/unit/Oracle/Mocks/CurveWrapper.sol create mode 100644 solidity/test/unit/Oracle/Mocks/Interfaces/I1inch.sol create mode 100644 solidity/test/unit/Oracle/Mocks/Interfaces/ICurveFactory.sol create mode 100644 solidity/test/unit/Oracle/Mocks/Interfaces/IStableSwap.sol create mode 100644 solidity/test/unit/Oracle/Mocks/SushiWrapper.sol create mode 100644 solidity/test/unit/Oracle/Mocks/UniswapV3Wrapper.sol create mode 100644 solidity/test/unit/Oracle/Mocks/UniswapWrapper.sol create mode 100644 solidity/test/unit/Oracle/Oracle.t.sol diff --git a/solidity/contracts/Oracle/Oracle.sol b/solidity/contracts/Oracle/Oracle.sol new file mode 100644 index 00000000..b3c7e0d6 --- /dev/null +++ b/solidity/contracts/Oracle/Oracle.sol @@ -0,0 +1,73 @@ +pragma solidity ^0.8.19; + +import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; +import {IWrapper} from '../../interfaces/Oracle/IWrapper.sol'; +import {IOracle} from '../../interfaces/Oracle/IOracle.sol'; + +contract Oracle is Ownable, IOracle { + mapping(address _tokenA => mapping(address _tokenB => IWrapper _wrapper)) public pairWrappers; + mapping(address _tokenA => IWrapper _wrapper) public tokenWrappers; + IWrapper public defaultWrapper; + mapping(string _wrapperName => IWrapper _wrapper) public wrapperRegistry; + + modifier checkWrapper(string memory _wrapperName) { + if (address(wrapperRegistry[_wrapperName]) == address(0)) revert WrapperNotRegistered(); + _; + } + + constructor() Ownable(msg.sender) {} + + function registerWrapper(string memory _wrapperName, IWrapper _wrapper) public onlyOwner { + wrapperRegistry[_wrapperName] = _wrapper; + + emit WrapperRegistered(_wrapperName, _wrapper); + } + + /// @dev Sets wrapper for a given pair, if the pair is quoted then this price is returned first + /// @dev Order of tokens doesn't matter + /// @param _tokenA First token in the pair + /// @param _tokenB Second token in the pair + /// @param _wrapperName Name of oracle wrapper to quote + function setPairWrapper( + address _tokenA, + address _tokenB, + string memory _wrapperName + ) external checkWrapper(_wrapperName) onlyOwner { + pairWrappers[_tokenA][_tokenB] = wrapperRegistry[_wrapperName]; + pairWrappers[_tokenB][_tokenA] = wrapperRegistry[_wrapperName]; + } + + /// @dev Sets wrapper for a given token, if the token is quoted then this price is returned if no pair is set + /// @param _token token whose wrapper is set + /// @param _wrapperName Name of oracle wrapper to quote + function setTokenWrapper(address _token, string memory _wrapperName) external checkWrapper(_wrapperName) onlyOwner { + tokenWrappers[_token] = wrapperRegistry[_wrapperName]; + } + + /// @dev Sets default, if the token and pair aren't registered then this is quoted as a last resort + /// @param _wrapperName Name of oracle wrapper to quote + function setDefaultWrapper(string memory _wrapperName) external checkWrapper(_wrapperName) onlyOwner { + defaultWrapper = wrapperRegistry[_wrapperName]; + } + + /// @dev Queries on-chain price data through a shared interface + /// @dev Pairs have priority over tokens and tokens over the default, which is the last resort + /// @param _tokenIn Token to be 'swapped' out of + /// @param _amountIn Amount of input token + /// @param _tokenOut Token to be 'swapped' into + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + if (address(pairWrappers[_tokenIn][_tokenOut]) != address(0)) { + return pairWrappers[_tokenIn][_tokenOut].getAmountOut(_tokenIn, _amountIn, _tokenOut); + } else if (address(tokenWrappers[_tokenIn]) != address(0)) { + return tokenWrappers[_tokenIn].getAmountOut(_tokenIn, _amountIn, _tokenOut); + } else if (address(defaultWrapper) != address(0)) { + return defaultWrapper.getAmountOut(_tokenIn, _amountIn, _tokenOut); + } + + revert NoWrapperSet(); + } +} diff --git a/solidity/contracts/Swapper/SwapperV3.sol b/solidity/contracts/Swapper/SwapperV3.sol index 5cf755d5..5895689b 100644 --- a/solidity/contracts/Swapper/SwapperV3.sol +++ b/solidity/contracts/Swapper/SwapperV3.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.19; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; -import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {IUniswapV2Router01} from '@uniswap/periphery/interfaces/IUniswapV2Router01.sol'; import {IUniswapV2Pair} from '@uniswap/core/interfaces/IUniswapV2Pair.sol'; import {ISwapperV3} from '../../interfaces/Swapper/ISwapperV3.sol'; diff --git a/solidity/interfaces/Oracle/IOracle.sol b/solidity/interfaces/Oracle/IOracle.sol new file mode 100644 index 00000000..72d750bd --- /dev/null +++ b/solidity/interfaces/Oracle/IOracle.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.8.19; + +import {IWrapper} from './IWrapper.sol'; + +interface IOracle { + error NoWrapperSet(); + error WrapperNotRegistered(); + + event WrapperRegistered(string wrapperName, IWrapper _wrapper); +} diff --git a/solidity/interfaces/Oracle/IWrapper.sol b/solidity/interfaces/Oracle/IWrapper.sol new file mode 100644 index 00000000..526fdf20 --- /dev/null +++ b/solidity/interfaces/Oracle/IWrapper.sol @@ -0,0 +1,5 @@ +pragma solidity ^0.8.19; + +interface IWrapper { + function getAmountOut(address tokenIn, uint256 amountIn, address tokenOut) external view returns (uint256 amountOut); +} diff --git a/solidity/test/unit/Oracle/Mocks/1inchWrapper.sol b/solidity/test/unit/Oracle/Mocks/1inchWrapper.sol new file mode 100644 index 00000000..f063d4bf --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/1inchWrapper.sol @@ -0,0 +1,28 @@ +pragma solidity ^0.8.19; + +import {I1inch} from './Interfaces/I1inch.sol'; +import {IWrapper} from '../../../../interfaces/Oracle/IWrapper.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +contract OneInchWrapper is IWrapper { + address constant _1inch = 0xC586BeF4a0992C495Cf22e1aeEE4E446CECDee0E; + + constructor() {} + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + (_amountOut,) = I1inch(_1inch).getExpectedReturn(IERC20(_tokenIn), IERC20(_tokenOut), _amountIn, 1, 0); + } + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut, + uint32 _timeAgo + ) public view returns (uint256 _amountOut) { + _amountOut = getAmountOut(_tokenIn, _amountIn, _tokenOut); + } +} diff --git a/solidity/test/unit/Oracle/Mocks/ChainlinkWrapper.sol b/solidity/test/unit/Oracle/Mocks/ChainlinkWrapper.sol new file mode 100644 index 00000000..e32ad700 --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/ChainlinkWrapper.sol @@ -0,0 +1,49 @@ +pragma solidity ^0.8.19; + +import {IWrapper} from '../../../../interfaces/Oracle/IWrapper.sol'; +import {FeedRegistryInterface} from '@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol'; + +contract ChainlinkWrapper is IWrapper { + FeedRegistryInterface constant _registry = FeedRegistryInterface(0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf); + address constant dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F; + address constant usdt = 0xdAC17F958D2ee523a2206206994597C13D831ec7; + address constant usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; + address constant wbtc = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; + + constructor() {} + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + if (_tokenIn == dai || _tokenIn == usdt || _tokenIn == usdc) { + _tokenIn = address(840); + } else if (_tokenIn == weth) { + _tokenIn = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + } else if (_tokenIn == wbtc) { + _tokenIn = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB; + } + + if (_tokenOut == dai || _tokenOut == usdt || _tokenOut == usdc) { + _tokenOut = address(840); + } else if (_tokenOut == weth) { + _tokenOut = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + } else if (_tokenOut == wbtc) { + _tokenOut = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB; + } + + (, int256 _price,,,) = _registry.latestRoundData(_tokenIn, _tokenOut); + _amountOut = _amountIn * uint256(_price) / 10 ** _registry.decimals(_tokenIn, _tokenOut); + } + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut, + uint32 _timeAgo + ) public view returns (uint256 _amountOut) { + _amountOut = getAmountOut(_tokenIn, _amountIn, _tokenOut); + } +} diff --git a/solidity/test/unit/Oracle/Mocks/CurveWrapper.sol b/solidity/test/unit/Oracle/Mocks/CurveWrapper.sol new file mode 100644 index 00000000..45a770b6 --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/CurveWrapper.sol @@ -0,0 +1,48 @@ +pragma solidity ^0.8.19; + +import {ICurveFactory} from './Interfaces/ICurveFactory.sol'; +import {IStableSwap} from './Interfaces/IStableSwap.sol'; +import {IWrapper} from '../../../../interfaces/Oracle/IWrapper.sol'; + +contract CurveWrapper is IWrapper { + address constant factory = 0xB9fC157394Af804a3578134A6585C0dc9cc990d4; + + constructor() {} + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + IStableSwap _pool = IStableSwap(getPool(_tokenIn, _tokenOut)); + uint256 _i; + uint256 _j; + + // Assumption is _tokenIn and _tokenOut are both in the coins list + // This holds true as long as the pool was derived from these addresses, so the pool must contain them + while (_pool.coins(_i) != _tokenIn) { + ++_i; + } + + while (_pool.coins(_j) != _tokenOut) { + ++_j; + } + + _amountOut = _pool.get_dy(int128(int256(_i)), int128(int256(_j)), _amountIn); + } + + function getPool(address _tokenIn, address _tokenOut) public view returns (address _pool) { + _pool = ICurveFactory(factory).find_pool_for_coins(_tokenIn, _tokenOut); + + if (_pool == address(0)) revert InvalidPair(); + } + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut, + uint32 _timeAgo + ) public view returns (uint256 _amountOut) { + _amountOut = getAmountOut(_tokenIn, _amountIn, _tokenOut); + } +} diff --git a/solidity/test/unit/Oracle/Mocks/Interfaces/I1inch.sol b/solidity/test/unit/Oracle/Mocks/Interfaces/I1inch.sol new file mode 100644 index 00000000..8ab212da --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/Interfaces/I1inch.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.8.19; + +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +interface I1inch { + function getExpectedReturn( + IERC20 fromToken, + IERC20 destToken, + uint256 amount, + uint256 parts, + uint256 flags + ) external view returns (uint256 returnAmount, uint256[] memory distribution); +} diff --git a/solidity/test/unit/Oracle/Mocks/Interfaces/ICurveFactory.sol b/solidity/test/unit/Oracle/Mocks/Interfaces/ICurveFactory.sol new file mode 100644 index 00000000..c1e4f503 --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/Interfaces/ICurveFactory.sol @@ -0,0 +1,5 @@ +pragma solidity ^0.8.19; + +interface ICurveFactory { + function find_pool_for_coins(address _from, address _to) external view returns (address _pool); +} diff --git a/solidity/test/unit/Oracle/Mocks/Interfaces/IStableSwap.sol b/solidity/test/unit/Oracle/Mocks/Interfaces/IStableSwap.sol new file mode 100644 index 00000000..d2a2892a --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/Interfaces/IStableSwap.sol @@ -0,0 +1,6 @@ +pragma solidity ^0.8.19; + +interface IStableSwap { + function get_dy(int128 _i, int128 _j, uint256 _dx) external view returns (uint256 _dy); + function coins(uint256 _i) external view returns (address _token); +} diff --git a/solidity/test/unit/Oracle/Mocks/SushiWrapper.sol b/solidity/test/unit/Oracle/Mocks/SushiWrapper.sol new file mode 100644 index 00000000..828d496d --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/SushiWrapper.sol @@ -0,0 +1,41 @@ +pragma solidity ^0.8.19; + +import {IWrapper} from '../../../../interfaces/Oracle/IWrapper.sol'; +import {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol'; +import {IUniswapV2Pair} from '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; +import {IUniswapV2Factory} from '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; + +contract SushiWrapper is IWrapper { + IUniswapV2Router02 constant router = IUniswapV2Router02(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); + IUniswapV2Factory constant factory = IUniswapV2Factory(0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac); + + constructor() {} + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + // need to sort tokens in the correct order + // generating pair address as outlined here: + (address _token0, address _token1) = _tokenIn < _tokenOut ? (_tokenIn, _tokenOut) : (_tokenOut, _tokenIn); + address _pairAddress = factory.getPair(_token0, _token1); + IUniswapV2Pair _pair = IUniswapV2Pair(_pairAddress); + (uint256 _reserve0, uint256 _reserve1,) = _pair.getReserves(); + + if (_tokenIn == _pair.token0()) { + _amountOut = router.getAmountOut(_amountIn, _reserve0, _reserve1); + } else { + _amountOut = router.getAmountOut(_amountIn, _reserve1, _reserve0); + } + } + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut, + uint32 _timeAgo + ) public view returns (uint256 _amountOut) { + _amountOut = getAmountOut(_tokenIn, _amountIn, _tokenOut); + } +} diff --git a/solidity/test/unit/Oracle/Mocks/UniswapV3Wrapper.sol b/solidity/test/unit/Oracle/Mocks/UniswapV3Wrapper.sol new file mode 100644 index 00000000..9937a52b --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/UniswapV3Wrapper.sol @@ -0,0 +1,113 @@ +pragma solidity ^0.8.19; + +import {IWrapper} from '../../../../interfaces/Oracle/IWrapper.sol'; +import {IUniswapV3Pool} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol'; +import {IUniswapV3Factory} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol'; +import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; +import '@uniswap/v3-core/contracts/libraries/TickMath.sol'; + +contract UniswapV3Wrapper is IWrapper { + IUniswapV3Factory constant _factory = IUniswapV3Factory(0x1F98431c8aD98523631AE4a59f267346ea31F984); + + constructor() {} + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + address _pool; + + // lowest fee pool found is the correct addresss + if (_factory.getPool(_tokenIn, _tokenOut, 100) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 100); + } else if (_factory.getPool(_tokenIn, _tokenOut, 500) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 500); + } else if (_factory.getPool(_tokenIn, _tokenOut, 3000) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 3000); + } else if (_factory.getPool(_tokenIn, _tokenOut, 10_000) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 10_000); + } else { + revert InvalidPair(); + } + + (int24 tick,) = consult(_pool, 1); + _amountOut = getQuoteAtTick(tick, uint128(_amountIn), _tokenIn, _tokenOut); + } + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut, + uint32 _timeAgo + ) public view returns (uint256 _amountOut) { + address _pool; + + // lowest fee pool found is the correct addresss + if (_factory.getPool(_tokenIn, _tokenOut, 100) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 100); + } else if (_factory.getPool(_tokenIn, _tokenOut, 500) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 500); + } else if (_factory.getPool(_tokenIn, _tokenOut, 3000) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 3000); + } else if (_factory.getPool(_tokenIn, _tokenOut, 10_000) != address(0)) { + _pool = _factory.getPool(_tokenIn, _tokenOut, 10_000); + } else { + revert InvalidPair(); + } + + (int24 tick,) = consult(_pool, _timeAgo); + _amountOut = getQuoteAtTick(tick, uint128(_amountIn), _tokenIn, _tokenOut); + } + + // pulled from OracleLibrary + // Couldn't use library methods directly since it had solc version <0.8 + // Minor changes made with casting + function consult( + address pool, + uint32 secondsAgo + ) internal view returns (int24 arithmeticMeanTick, uint128 harmonicMeanLiquidity) { + require(secondsAgo != 0, 'BP'); + + uint32[] memory secondsAgos = new uint32[](2); + secondsAgos[0] = secondsAgo; + secondsAgos[1] = 0; + + (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = + IUniswapV3Pool(pool).observe(secondsAgos); + + int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0]; + uint160 secondsPerLiquidityCumulativesDelta = + secondsPerLiquidityCumulativeX128s[1] - secondsPerLiquidityCumulativeX128s[0]; + + arithmeticMeanTick = int24(tickCumulativesDelta / int32(secondsAgo)); + // Always round to negative infinity + if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int32(secondsAgo) != 0)) arithmeticMeanTick--; + + // We are multiplying here instead of shifting to ensure that harmonicMeanLiquidity doesn't overflow uint128 + uint192 secondsAgoX160 = uint192(secondsAgo) * type(uint160).max; + harmonicMeanLiquidity = uint128(secondsAgoX160 / (uint192(secondsPerLiquidityCumulativesDelta) << 32)); + } + + function getQuoteAtTick( + int24 tick, + uint128 baseAmount, + address baseToken, + address quoteToken + ) internal pure returns (uint256 quoteAmount) { + uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); + + // Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself + if (sqrtRatioX96 <= type(uint128).max) { + uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96; + quoteAmount = baseToken < quoteToken + ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192) + : FullMath.mulDiv(1 << 192, baseAmount, ratioX192); + } else { + uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64); + quoteAmount = baseToken < quoteToken + ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128) + : FullMath.mulDiv(1 << 128, baseAmount, ratioX128); + } + } +} diff --git a/solidity/test/unit/Oracle/Mocks/UniswapWrapper.sol b/solidity/test/unit/Oracle/Mocks/UniswapWrapper.sol new file mode 100644 index 00000000..616717c3 --- /dev/null +++ b/solidity/test/unit/Oracle/Mocks/UniswapWrapper.sol @@ -0,0 +1,57 @@ +pragma solidity ^0.8.19; + +import {IWrapper} from '../../../../interfaces/Oracle/IWrapper.sol'; +import {IUniswapV2Router02} from '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol'; +import {IUniswapV2Pair} from '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; + +contract UniswapWrapper is IWrapper { + IUniswapV2Router02 constant router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); + address constant factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; + + constructor() {} + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut + ) public view returns (uint256 _amountOut) { + // need to sort tokens in the correct order + // generating pair address as outlined here: + (address _token0, address _token1) = _tokenIn < _tokenOut ? (_tokenIn, _tokenOut) : (_tokenOut, _tokenIn); + address _pairAddress = address( + uint160( + uint256( + keccak256( + abi.encodePacked( + hex'ff', + factory, + keccak256(abi.encodePacked(_token0, _token1)), + hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' + ) + ) + ) + ) + ); + + if (_pairAddress == address(0)) { + revert InvalidPair(); + } + IUniswapV2Pair _pair = IUniswapV2Pair(_pairAddress); + (uint256 _reserve0, uint256 _reserve1,) = _pair.getReserves(); + + if (_tokenIn == _pair.token0()) { + _amountOut = router.getAmountOut(_amountIn, _reserve0, _reserve1); + } else { + _amountOut = router.getAmountOut(_amountIn, _reserve1, _reserve0); + } + } + + function getAmountOut( + address _tokenIn, + uint256 _amountIn, + address _tokenOut, + uint32 _timeAgo + ) public view returns (uint256 _amountOut) { + _amountOut = getAmountOut(_tokenIn, _amountIn, _tokenOut); + } +} diff --git a/solidity/test/unit/Oracle/Oracle.t.sol b/solidity/test/unit/Oracle/Oracle.t.sol new file mode 100644 index 00000000..5efd03e3 --- /dev/null +++ b/solidity/test/unit/Oracle/Oracle.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.19; + +import {Test, console2} from 'forge-std/Test.sol'; +import {Oracle} from '../../../contracts/Oracle/Oracle.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +contract OracleTest is Test { + Oracle public oracle; + + IERC20 dai; + IERC20 uni; + IERC20 usdt; + + function setUp() public { + vm.createSelectFork(vm.envString('MAINNET_RPC')); + dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); // DAI token + uni = IERC20(0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984); // UNI token + usdt = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); // USDT token + + oracle = new Oracle(); + } + + function testPriority() public { + oracle.registerWrapper('UniswapV2', _wrapper); + oracle.registerWrapper('Curve', _wrapper); + oracle.registerWrapper('1Inch', _wrapper); + } +}