diff --git a/.github/actions/setup-repo/action.yml b/.github/actions/setup-repo/action.yml
new file mode 100644
index 0000000..1932a67
--- /dev/null
+++ b/.github/actions/setup-repo/action.yml
@@ -0,0 +1,35 @@
+name: Setup repo
+description: Runs all steps to setup the repo (install node_modules, build, etc...)
+inputs:
+  registry-token:
+    description: 'PAT to access registries'
+runs:
+  using: 'composite'
+  steps:
+    - name: Get yarn cache directory path
+      id: yarn-cache-dir-path
+      shell: bash
+      run: |
+        echo "::set-output name=dir::$(yarn cache dir)"
+        echo "::set-output name=version::$(yarn -v)"
+
+    - uses: actions/setup-node@v3
+      with:
+        node-version: '20'
+
+    - uses: actions/cache@v2
+      id: yarn-cache
+      with:
+        path: |
+          **/node_modules
+          ${{ steps.yarn-cache-dir-path.outputs.dir }}
+
+        key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+        restore-keys: |
+          ${{ runner.os }}-yarn-
+
+    - name: Install dependencies
+      shell: bash
+      run: echo "//npm.pkg.github.com/:_authToken=$GH_REGISTRY_ACCESS_TOKEN" >> .npmrc && yarn install --frozen-lockfile --verbose  && rm -f .npmrc
+      env:
+        GH_REGISTRY_ACCESS_TOKEN: ${{ inputs.registry-token }}
diff --git a/.github/workflows/ci-deep.yml b/.github/workflows/ci-deep.yml
index 31be761..aa8d35d 100644
--- a/.github/workflows/ci-deep.yml
+++ b/.github/workflows/ci-deep.yml
@@ -1,13 +1,13 @@
-name: "CI Deep"
+name: 'CI Deep'
 
 on:
   schedule:
-    - cron: "0 3 * * 0" # at 3:00am UTC every Sunday
+    - cron: '0 3 * * 0' # at 3:00am UTC every Sunday
   workflow_dispatch:
     inputs:
       fuzzRuns:
-        default: "10000"
-        description: "Unit: number of fuzz runs."
+        default: '10000'
+        description: 'Unit: number of fuzz runs.'
         required: false
 
 jobs:
@@ -19,7 +19,12 @@ jobs:
       - uses: actions/setup-node@v3
         with:
           node-version: 18
-          cache: "yarn"
+          cache: 'yarn'
+
+      - name: Setup repo
+        uses: ./.github/actions/setup-repo
+        with:
+          registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }}
 
       - name: Install dependencies
         run: yarn install
@@ -27,7 +32,7 @@ jobs:
       - name: Run solhint
         run: yarn lint:check
 
-      - name: "Add lint summary"
+      - name: 'Add lint summary'
         run: |
           echo "## Lint result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
@@ -37,12 +42,17 @@ jobs:
     steps:
       - uses: actions/checkout@v3
         with:
-          submodules: "recursive"
+          submodules: 'recursive'
 
       - uses: actions/setup-node@v3
         with:
           node-version: 18
-          cache: "yarn"
+          cache: 'yarn'
+
+      - name: Setup repo
+        uses: ./.github/actions/setup-repo
+        with:
+          registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }}
 
       - name: Install dependencies
         run: yarn install --frozen-lockfile
@@ -58,10 +68,10 @@ jobs:
       - name: Compile foundry
         run: yarn foundry:compile --sizes
 
-      - name: "Cache the build so that it can be re-used by the other jobs"
-        uses: "actions/cache/save@v3"
+      - name: 'Cache the build so that it can be re-used by the other jobs'
+        uses: 'actions/cache/save@v3'
         with:
-          key: "build-${{ github.sha }}"
+          key: 'build-${{ github.sha }}'
           path: |
             cache-forge
             out
@@ -70,13 +80,13 @@ jobs:
             typechain
             node_modules
 
-      - name: "Add build summary"
+      - name: 'Add build summary'
         run: |
           echo "## Build result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
 
   hardhat-tests:
-    needs: ["build", "lint"]
+    needs: ['build', 'lint']
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
@@ -84,13 +94,13 @@ jobs:
       - uses: actions/setup-node@v3
         with:
           node-version: 18
-          cache: "yarn"
+          cache: 'yarn'
 
-      - name: "Restore the cached build"
-        uses: "actions/cache/restore@v3"
+      - name: 'Restore the cached build'
+        uses: 'actions/cache/restore@v3'
         with:
           fail-on-cache-miss: true
-          key: "build-${{ github.sha }}"
+          key: 'build-${{ github.sha }}'
           path: |
             cache-forge
             out
@@ -108,29 +118,29 @@ jobs:
           CI: true
           ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }}
 
-      - name: "Add test summary"
+      - name: 'Add test summary'
         run: |
           echo "## Hardhat Unit tests result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
 
   foundry-tests:
-    needs: ["build", "lint"]
+    needs: ['build', 'lint']
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
         with:
-          submodules: "recursive"
+          submodules: 'recursive'
 
       - name: Install Foundry
         uses: foundry-rs/foundry-toolchain@v1
         with:
           version: nightly
 
-      - name: "Restore the cached build"
-        uses: "actions/cache/restore@v3"
+      - name: 'Restore the cached build'
+        uses: 'actions/cache/restore@v3'
         with:
           fail-on-cache-miss: true
-          key: "build-${{ github.sha }}"
+          key: 'build-${{ github.sha }}'
           path: |
             cache-forge
             out
@@ -145,7 +155,7 @@ jobs:
           ETH_NODE_URI_OPTIMISM: ${{ secrets.ETH_NODE_URI_OPTIMISM }}
           FOUNDRY_FUZZ_RUNS: ${{ github.event.inputs.fuzzRuns || '10000' }}
 
-      - name: "Add test summary"
+      - name: 'Add test summary'
         run: |
           echo "## Foundry Unit tests result" >> $GITHUB_STEP_SUMMARY
-          echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
\ No newline at end of file
+          echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2ae5850..963a6ad 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,7 +5,7 @@ on:
   pull_request:
   push:
     branches:
-      - "main"
+      - 'main'
 
 jobs:
   lint:
@@ -16,7 +16,12 @@ jobs:
       - uses: actions/setup-node@v3
         with:
           node-version: 18
-          cache: "yarn"
+          cache: 'yarn'
+
+      - name: Setup repo
+        uses: ./.github/actions/setup-repo
+        with:
+          registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }}
 
       - name: Install dependencies
         run: yarn install
@@ -24,7 +29,7 @@ jobs:
       - name: Run solhint
         run: yarn lint:check
 
-      - name: "Add lint summary"
+      - name: 'Add lint summary'
         run: |
           echo "## Lint result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
@@ -33,12 +38,17 @@ jobs:
     steps:
       - uses: actions/checkout@v3
         with:
-          submodules: "recursive"
+          submodules: 'recursive'
 
       - uses: actions/setup-node@v3
         with:
           node-version: 18
-          cache: "yarn"
+          cache: 'yarn'
+
+      - name: Setup repo
+        uses: ./.github/actions/setup-repo
+        with:
+          registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }}
 
       - name: Install dependencies
         run: yarn install --frozen-lockfile
@@ -54,10 +64,10 @@ jobs:
       - name: Compile foundry
         run: yarn foundry:compile --sizes
 
-      - name: "Cache the build so that it can be re-used by the other jobs"
-        uses: "actions/cache/save@v3"
+      - name: 'Cache the build so that it can be re-used by the other jobs'
+        uses: 'actions/cache/save@v3'
         with:
-          key: "build-${{ github.sha }}"
+          key: 'build-${{ github.sha }}'
           path: |
             cache-forge
             out
@@ -66,13 +76,13 @@ jobs:
             typechain
             node_modules
 
-      - name: "Add build summary"
+      - name: 'Add build summary'
         run: |
           echo "## Build result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
 
   hardhat-tests:
-    needs: ["build", "lint"]
+    needs: ['build', 'lint']
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
@@ -80,13 +90,13 @@ jobs:
       - uses: actions/setup-node@v3
         with:
           node-version: 18
-          cache: "yarn"
+          cache: 'yarn'
 
-      - name: "Restore the cached build"
-        uses: "actions/cache/restore@v3"
+      - name: 'Restore the cached build'
+        uses: 'actions/cache/restore@v3'
         with:
           fail-on-cache-miss: true
-          key: "build-${{ github.sha }}"
+          key: 'build-${{ github.sha }}'
           path: |
             cache-forge
             out
@@ -95,7 +105,6 @@ jobs:
             typechain
             node_modules
       - run: export NODE_OPTIONS=--max_old_space_size=11264
-
       - name: Run unit tests
         run: yarn hardhat:test
         env:
@@ -103,29 +112,29 @@ jobs:
           CI: true
           ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }}
 
-      - name: "Add test summary"
+      - name: 'Add test summary'
         run: |
           echo "## Hardhat Unit tests result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
 
   foundry-tests:
-    needs: ["build", "lint"]
+    needs: ['build', 'lint']
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
         with:
-          submodules: "recursive"
+          submodules: 'recursive'
 
       - name: Install Foundry
         uses: foundry-rs/foundry-toolchain@v1
         with:
           version: nightly
 
-      - name: "Restore the cached build"
-        uses: "actions/cache/restore@v3"
+      - name: 'Restore the cached build'
+        uses: 'actions/cache/restore@v3'
         with:
           fail-on-cache-miss: true
-          key: "build-${{ github.sha }}"
+          key: 'build-${{ github.sha }}'
           path: |
             cache-forge
             out
@@ -137,39 +146,10 @@ jobs:
       - name: Run Foundry tests
         run: yarn foundry:test
         env:
-          FOUNDRY_FUZZ_RUNS: "5000"
+          FOUNDRY_FUZZ_RUNS: '5000'
           ETH_NODE_URI_OPTIMISM: ${{ secrets.ETH_NODE_URI_OPTIMISM }}
 
-      - name: "Add test summary"
+      - name: 'Add test summary'
         run: |
           echo "## Foundry Unit tests result" >> $GITHUB_STEP_SUMMARY
           echo "✅ Passed" >> $GITHUB_STEP_SUMMARY
-
-  slither-analyze:
-    needs: ["build", "lint"]
-    permissions:
-      actions: "read"
-      contents: "read"
-      security-events: "write"
-    runs-on: "ubuntu-latest"
-    steps:
-      - name: "Check out the repo"
-        uses: "actions/checkout@v3"
-
-      - name: "Run Slither analysis"
-        uses: "crytic/slither-action@v0.3.0"
-        id: "slither"
-        with:
-          fail-on: "none"
-          sarif: "results.sarif"
-          node-version: 18
-
-      - name: "Upload SARIF file to GitHub code scanning"
-        uses: "github/codeql-action/upload-sarif@v2"
-        with:
-          sarif_file: ${{ steps.slither.outputs.sarif }}
-
-      - name: "Add Slither summary"
-        run: |
-          echo "## Slither result" >> $GITHUB_STEP_SUMMARY
-          echo "✅ Uploaded to GitHub code scanning" >> $GITHUB_STEP_SUMMARY
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..af66bba
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+@angleprotocol:registry=https://npm.pkg.github.com
diff --git a/contracts/middleman/MerklFraxIncentivizationHandler.sol b/contracts/middleman/MerklFraxIncentivizationHandler.sol
new file mode 100644
index 0000000..c67794d
--- /dev/null
+++ b/contracts/middleman/MerklFraxIncentivizationHandler.sol
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-3.0
+
+pragma solidity ^0.8.17;
+
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+
+import "../DistributionCreator.sol";
+
+/// @title MerklFraxIncentivizationHandler
+/// @author Angle Labs, Inc.
+/// @notice Manages the transfer of rewards sent by FRAX `IncentivizingLiquidityAmo` contract to the
+/// `DistributionCreator` contract
+/// @dev This contract is built under the assumption that the `DistributionCreator` contract has already whitelisted
+/// this contract for it to distribute rewards without having to sign a message
+contract MerklFraxIncentivizationHandler is Ownable {
+    using SafeERC20 for IERC20;
+
+    /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                                                      PARAMETERS                                                    
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
+
+    address public operatorAddress;
+
+    /// @notice Maps a gauge, incentive token pair to its reward parameters
+    mapping(address => mapping(address => DistributionParameters)) public gaugeParams;
+
+    /// @notice Maps an incentive token to a set of (pool, leftovers)
+    /// @dev Merkl imposes that each token distribution comes with a minimum amount per hour
+    /// We use this mapping to keep track of leftovers to be distributed during future distributions
+    mapping(address => mapping(address => uint256)) public leftovers;
+
+    /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                                                   MODIFIER / EVENT                                                 
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
+
+    modifier onlyByOwnerOperator() {
+        require(msg.sender == operatorAddress || msg.sender == owner(), "Not owner or operator");
+        _;
+    }
+
+    event GaugeSet(address indexed gauge, address indexed incentiveTokenAddress);
+
+    constructor(address _operatorAddress) Ownable() {
+        operatorAddress = _operatorAddress;
+    }
+
+    /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                                                      REFERENCES                                                    
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
+
+    /// @notice Address of the Merkl contract managing rewards to be distributed
+    /// @dev Address is the same across the different chains on which it is deployed
+    function merklDistributionCreator() public view virtual returns (DistributionCreator) {
+        return DistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd);
+    }
+
+    /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                                                  EXTERNAL FUNCTIONS                                                
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
+
+    /// @notice Specifies the reward distribution parameters for `poolAddress`
+    function setGauge(
+        address poolAddress,
+        address incentiveTokenAddress,
+        DistributionParameters memory params
+    ) external onlyByOwnerOperator {
+        if (poolAddress == address(0) || incentiveTokenAddress == address(0)) revert InvalidParams();
+        gaugeParams[poolAddress][incentiveTokenAddress] = params;
+        emit GaugeSet(poolAddress, incentiveTokenAddress);
+    }
+
+    /// @notice Sets the operator of the contract
+    function setOperator(address _operatorAddress) external onlyByOwnerOperator {
+        operatorAddress = _operatorAddress;
+    }
+
+    /// @notice Function called by FRAX contract to stream rewards to `poolAddress`
+    /// @dev Params for the incentivization of the pool must have been set prior to any call for
+    /// a `(poolAddress,incentiveTokenAddress)` pair
+    function incentivizePool(
+        address poolAddress,
+        address,
+        address,
+        address incentiveTokenAddress,
+        uint256,
+        uint256 amount
+    ) external {
+        IERC20(incentiveTokenAddress).safeTransferFrom(msg.sender, address(this), amount);
+        DistributionParameters memory params = gaugeParams[poolAddress][incentiveTokenAddress];
+        if (params.uniV3Pool == address(0)) revert InvalidParams();
+        DistributionCreator creator = merklDistributionCreator();
+        // Minimum amount of incentive tokens to be distributed per hour
+        uint256 minAmount = creator.rewardTokenMinAmounts(incentiveTokenAddress) * params.numEpoch;
+        params.epochStart = uint32(block.timestamp);
+        // Adding the leftover amounts to the total amount to be distributed
+        uint256 leftover = leftovers[incentiveTokenAddress][poolAddress];
+        amount += leftover;
+        params.amount = amount;
+        if (amount > 0) {
+            if (amount > minAmount) {
+                if (leftover > 0) leftovers[incentiveTokenAddress][poolAddress] = 0;
+                _handleIncentiveTokenAllowance(IERC20(incentiveTokenAddress), address(creator), amount);
+                merklDistributionCreator().createDistribution(params);
+            } else {
+                leftovers[incentiveTokenAddress][poolAddress] = amount;
+            }
+        }
+    }
+
+    /// @notice Restores the allowance for the ANGLE token to the `DistributionCreator` contract
+    function _handleIncentiveTokenAllowance(IERC20 incentiveTokenAddress, address spender, uint256 amount) internal {
+        uint256 currentAllowance = incentiveTokenAddress.allowance(address(this), spender);
+        if (currentAllowance < amount) incentiveTokenAddress.safeIncreaseAllowance(spender, amount - currentAllowance);
+    }
+}
diff --git a/contracts/mock/MockMerklFraxIncentivizationHandler.sol b/contracts/mock/MockMerklFraxIncentivizationHandler.sol
new file mode 100644
index 0000000..1012c89
--- /dev/null
+++ b/contracts/mock/MockMerklFraxIncentivizationHandler.sol
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-3.0
+
+pragma solidity ^0.8.17;
+
+import "../middleman/MerklFraxIncentivizationHandler.sol";
+
+contract MockMerklFraxIncentivizationHandler is MerklFraxIncentivizationHandler {
+    DistributionCreator public manager;
+
+    constructor(address _operator) MerklFraxIncentivizationHandler(_operator) {}
+
+    function merklDistributionCreator() public view override returns (DistributionCreator) {
+        return manager;
+    }
+
+    function setAddresses(DistributionCreator _manager) external {
+        manager = _manager;
+    }
+}
diff --git a/deploy/1_distributionCreator.ts b/deploy/1_distributionCreator.ts
index d546853..05ec629 100644
--- a/deploy/1_distributionCreator.ts
+++ b/deploy/1_distributionCreator.ts
@@ -1,4 +1,3 @@
-import { ChainId, registry } from '@angleprotocol/sdk';
 import { DeployFunction } from 'hardhat-deploy/types';
 import yargs from 'yargs';
 
@@ -22,7 +21,7 @@ const func: DeployFunction = async ({ deployments, ethers, network }) => {
     core = registry(network.config.chainId as ChainId)?.Merkl?.CoreMerkl!;
   }
   */
-  
+
   console.log(deployer.address);
   console.log('Now deploying DistributionCreator');
   console.log('Starting with the implementation');
diff --git a/deploy/2_middleman.ts b/deploy/2_middleman.ts
index 1e5b470..e6c0147 100644
--- a/deploy/2_middleman.ts
+++ b/deploy/2_middleman.ts
@@ -2,8 +2,6 @@ import { ChainId, registry } from '@angleprotocol/sdk';
 import { DeployFunction } from 'hardhat-deploy/types';
 import yargs from 'yargs';
 
-import { DistributionCreator, DistributionCreator__factory } from '../typechain';
-import { parseAmount } from '../utils/bignumber';
 const argv = yargs.env('').boolean('ci').parseSync();
 
 const func: DeployFunction = async ({ deployments, ethers, network }) => {
diff --git a/deploy/merklFraxMiddleman.ts b/deploy/merklFraxMiddleman.ts
new file mode 100644
index 0000000..12288dc
--- /dev/null
+++ b/deploy/merklFraxMiddleman.ts
@@ -0,0 +1,30 @@
+import { DeployFunction } from 'hardhat-deploy/types';
+import yargs from 'yargs';
+
+const argv = yargs.env('').boolean('ci').parseSync();
+
+const func: DeployFunction = async ({ deployments, ethers, network }) => {
+  const { deploy } = deployments;
+  const { deployer } = await ethers.getNamedSigners();
+  let core: string;
+
+  const implementationName = 'MerklFraxIncentivizationHandler';
+
+  console.log(`Now deploying ${implementationName}`);
+  console.log('Starting with the implementation');
+
+  await deploy(implementationName, {
+    contract: implementationName,
+    from: deployer.address,
+    args: [deployer.address],
+    log: !argv.ci,
+  });
+
+  const implementationAddress = (await ethers.getContract(implementationName)).address;
+
+  console.log(`Successfully deployed the contract ${implementationName} at ${implementationAddress}`);
+  console.log('');
+};
+
+func.tags = ['fraxMiddleman'];
+export default func;
diff --git a/deploy/mockCoreBorrow.ts b/deploy/mockCoreBorrow.ts
index b0a8bf7..f31ff86 100644
--- a/deploy/mockCoreBorrow.ts
+++ b/deploy/mockCoreBorrow.ts
@@ -1,4 +1,3 @@
-import { ChainId, CONTRACTS_ADDRESSES, registry } from '@angleprotocol/sdk';
 import { DeployFunction } from 'hardhat-deploy/types';
 import yargs from 'yargs';
 
diff --git a/package.json b/package.json
index f9fba48..54c02c2 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
     "url": "https://github.com/AngleProtocol/merkl-contracts/issues"
   },
   "devDependencies": {
-    "@angleprotocol/sdk": "3.0.87",
+    "@angleprotocol/sdk": "0.21.1",
     "@ethersproject/abi": "^5.7.0",
     "@ethersproject/providers": "^5.7.1",
     "@nomicfoundation/hardhat-chai-matchers": "^1.0.3",
@@ -73,7 +73,7 @@
     "eslint-plugin-promise": "^6.0.0",
     "eslint-plugin-standard": "5.0.0",
     "ethers": "^5.7.1",
-    "hardhat": "^2.12.6",
+    "hardhat": "^2.19.0",
     "hardhat-abi-exporter": "2.2.1",
     "hardhat-contract-sizer": "2.0.3",
     "hardhat-deploy": "^0.11.23",
diff --git a/scripts/mainnet-fork/migrationAngleDistributor.ts b/scripts/mainnet-fork/migrationAngleDistributor.ts
deleted file mode 100644
index f19358e..0000000
--- a/scripts/mainnet-fork/migrationAngleDistributor.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk';
-import { deployments, ethers, network, web3 } from 'hardhat';
-import yargs from 'yargs';
-
-import { deployUpgradeableUUPS, increaseTime, ZERO_ADDRESS } from '../../test/hardhat/utils/helpers';
-import {
-  AngleDistributor,
-  AngleDistributor__factory,
-  DistributionCreator,
-  ERC20,
-  ERC20__factory,
-  MerkleRewardManager__factory,
-  MockMerklGaugeMiddleman,
-  MockMerklGaugeMiddleman__factory,
-  ProxyAdmin,
-  ProxyAdmin__factory,
-} from '../../typechain';
-import { formatAmount, parseAmount } from '../../utils/bignumber';
-
-const argv = yargs.env('').boolean('ci').parseSync();
-
-async function main() {
-  let manager: DistributionCreator;
-  let angleDistributor: AngleDistributor;
-  let middleman: MockMerklGaugeMiddleman;
-  let angle: ERC20;
-  let params: any;
-
-  const { deploy } = deployments;
-  const [deployer] = await ethers.getSigners();
-  const proxyAdminAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].ProxyAdmin!;
-  const governor = CONTRACTS_ADDRESSES[ChainId.MAINNET].Governor! as string;
-  const coreBorrow = CONTRACTS_ADDRESSES[ChainId.MAINNET].CoreBorrow! as string;
-  const distributor = CONTRACTS_ADDRESSES[ChainId.MAINNET].Distributor! as string;
-  const angleDistributorAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].AngleDistributor! as string;
-  const angleAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].ANGLE! as string;
-  const agEURAddress = '0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8';
-  // agEUR-USDC gauge address
-  const gaugeAddr = '0xEB7547a8a734b6fdDBB8Ce0C314a9E6485100a3C';
-
-  params = {
-    uniV3Pool: '0x735a26a57a0a0069dfabd41595a970faf5e1ee8b',
-    token: angleAddress,
-    positionWrappers: [],
-    wrapperTypes: [],
-    amount: parseAmount.gwei('100000'),
-    propToken0: 4000,
-    propToken1: 2000,
-    propFees: 4000,
-    isOutOfRangeIncentivized: 0,
-    epochStart: 0,
-    numEpoch: 168,
-    boostedReward: 0,
-    boostingAddress: ZERO_ADDRESS,
-    rewardId: web3.utils.soliditySha3('TEST') as string,
-    additionalData: web3.utils.soliditySha3('test2ng') as string,
-  };
-
-  await network.provider.request({
-    method: 'hardhat_impersonateAccount',
-    params: [governor],
-  });
-  await network.provider.send('hardhat_setBalance', [governor, '0x10000000000000000000000000000']);
-  const governorSigner = await ethers.provider.getSigner(governor);
-
-  console.log('First deploying implementation for distributor');
-  await deploy('AngleDistributor_NewImplementation', {
-    contract: 'AngleDistributor',
-    from: deployer.address,
-    log: !argv.ci,
-  });
-  console.log('Success');
-
-  const distributorImplementationAddress = (await deployments.get('AngleDistributor_NewImplementation')).address;
-
-  const contractProxyAdmin = new ethers.Contract(
-    proxyAdminAddress,
-    ProxyAdmin__factory.createInterface(),
-    governorSigner,
-  ) as ProxyAdmin;
-
-  angleDistributor = new ethers.Contract(
-    angleDistributorAddress,
-    AngleDistributor__factory.createInterface(),
-    governorSigner,
-  ) as AngleDistributor;
-
-  angle = new ethers.Contract(angleAddress, ERC20__factory.createInterface(), governorSigner) as ERC20;
-
-  console.log('Now performing the upgrades');
-  await (
-    await contractProxyAdmin.connect(governorSigner).upgrade(angleDistributorAddress, distributorImplementationAddress)
-  ).wait();
-  console.log('Success');
-
-  manager = (await deployUpgradeableUUPS(new MerkleRewardManager__factory(deployer))) as DistributionCreator;
-  await manager.initialize(coreBorrow, distributor, parseAmount.gwei('0.1'));
-
-  middleman = (await new MockMerklGaugeMiddleman__factory(deployer).deploy(coreBorrow)) as MockMerklGaugeMiddleman;
-
-  await middleman.setAddresses(angleDistributorAddress, angleAddress, manager.address);
-
-  console.log('Toggling signature whitelist');
-  await (await manager.connect(governorSigner).toggleSigningWhitelist(middleman.address)).wait();
-  console.log('Toggling token whitelist');
-  await manager.connect(governorSigner).toggleTokenWhitelist(agEURAddress);
-
-  console.log('Setting the gauge on the middleman');
-  await middleman.connect(governorSigner).setGauge(gaugeAddr, params);
-  console.log('Setting the middleman as a delegate for the gauge');
-  await angleDistributor.connect(governorSigner).setDelegateGauge(gaugeAddr, middleman.address, true);
-  console.log('Setting allowance');
-  await middleman.connect(governorSigner).setAngleAllowance();
-  console.log(middleman.address);
-
-  await increaseTime(86400 * 7);
-
-  const angleBalanceDistr = await angle.balanceOf(distributor);
-  console.log(formatAmount.ether(angleBalanceDistr.toString()));
-  await angleDistributor.connect(governorSigner).distributeReward(gaugeAddr);
-  const angleBalanceDistr1 = await angle.balanceOf(distributor);
-  console.log(formatAmount.ether(angleBalanceDistr1.toString()));
-  await angleDistributor.connect(governorSigner).distributeReward(gaugeAddr);
-  const angleBalanceDistr2 = await angle.balanceOf(distributor);
-  console.log(formatAmount.ether(angleBalanceDistr2.toString()));
-  await increaseTime(86400 * 7);
-  await angleDistributor.connect(governorSigner).distributeReward(gaugeAddr);
-  const angleBalanceDistr3 = await angle.balanceOf(distributor);
-  console.log(formatAmount.ether(angleBalanceDistr3.toString()));
-}
-
-main().catch(error => {
-  console.error(error);
-  process.exit(1);
-});
diff --git a/test/hardhat/middleman/merklFraxIncentivizationHandler.test.ts b/test/hardhat/middleman/merklFraxIncentivizationHandler.test.ts
new file mode 100644
index 0000000..b0e2a73
--- /dev/null
+++ b/test/hardhat/middleman/merklFraxIncentivizationHandler.test.ts
@@ -0,0 +1,384 @@
+import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
+import { expect } from 'chai';
+import { parseEther, solidityKeccak256 } from 'ethers/lib/utils';
+import { contract, ethers, web3 } from 'hardhat';
+
+import {
+  DistributionCreator,
+  DistributionCreator__factory,
+  MockCoreBorrow,
+  MockCoreBorrow__factory,
+  MockMerklFraxIncentivizationHandler,
+  MockMerklFraxIncentivizationHandler__factory,
+  MockToken,
+  MockToken__factory,
+  MockUniswapV3Pool,
+  MockUniswapV3Pool__factory,
+} from '../../../typechain';
+import { parseAmount } from '../../../utils/bignumber';
+import { inReceipt } from '../utils/expectEvent';
+import { deployUpgradeableUUPS, latestTime, MAX_UINT256, ZERO_ADDRESS } from '../utils/helpers';
+
+contract('MerklFraxIncentivizerHandler', () => {
+  let deployer: SignerWithAddress;
+  let alice: SignerWithAddress;
+  let bob: SignerWithAddress;
+  let governor: SignerWithAddress;
+  let guardian: SignerWithAddress;
+  let angle: MockToken;
+  let pool: MockUniswapV3Pool;
+  let agEUR: string;
+
+  let manager: DistributionCreator;
+  let middleman: MockMerklFraxIncentivizationHandler;
+  let core: MockCoreBorrow;
+  let startTime: number;
+  // eslint-disable-next-line
+  let params: any;
+
+  beforeEach(async () => {
+    [deployer, alice, bob, governor, guardian] = await ethers.getSigners();
+    angle = (await new MockToken__factory(deployer).deploy('ANGLE', 'ANGLE', 18)) as MockToken;
+    core = (await new MockCoreBorrow__factory(deployer).deploy()) as MockCoreBorrow;
+    pool = (await new MockUniswapV3Pool__factory(deployer).deploy()) as MockUniswapV3Pool;
+    middleman = (await new MockMerklFraxIncentivizationHandler__factory(deployer).deploy(
+      deployer.address,
+    )) as MockMerklFraxIncentivizationHandler;
+    await core.toggleGuardian(guardian.address);
+    await core.toggleGovernor(governor.address);
+    manager = (await deployUpgradeableUUPS(new DistributionCreator__factory(deployer))) as DistributionCreator;
+    await manager.initialize(core.address, bob.address, parseAmount.gwei('0.1'));
+    startTime = await latestTime();
+    params = {
+      uniV3Pool: pool.address,
+      rewardToken: angle.address,
+      positionWrappers: [alice.address, bob.address, deployer.address],
+      wrapperTypes: [0, 1, 2],
+      amount: parseEther('1'),
+      propToken0: 4000,
+      propToken1: 2000,
+      propFees: 4000,
+      isOutOfRangeIncentivized: 0,
+      epochStart: startTime,
+      numEpoch: 1,
+      boostedReward: 0,
+      boostingAddress: ZERO_ADDRESS,
+      rewardId: web3.utils.soliditySha3('TEST') as string,
+      additionalData: web3.utils.soliditySha3('test2ng') as string,
+    };
+    agEUR = '0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8';
+    await angle.mint(alice.address, parseEther('1000'));
+    await angle.connect(alice).approve(middleman.address, MAX_UINT256);
+    await manager.connect(guardian).toggleTokenWhitelist(agEUR);
+    await manager.connect(guardian).toggleSigningWhitelist(middleman.address);
+    await manager.connect(guardian).setRewardTokenMinAmounts([angle.address], [1]);
+    await middleman.setAddresses(manager.address);
+  });
+  describe('initializer', () => {
+    it('success - values initialized', async () => {
+      expect(await middleman.operatorAddress()).to.be.equal(deployer.address);
+      expect(await middleman.merklDistributionCreator()).to.be.equal(manager.address);
+    });
+  });
+  describe('setOperator', () => {
+    it('reverts - access control', async () => {
+      await expect(middleman.connect(alice).setOperator(alice.address)).to.be.revertedWith('Not owner or operator');
+      await expect(middleman.connect(bob).setOperator(alice.address)).to.be.revertedWith('Not owner or operator');
+      expect(await middleman.operatorAddress()).to.be.equal(deployer.address);
+      expect(await middleman.owner()).to.be.equal(deployer.address);
+      await middleman.connect(deployer).transferOwnership(bob.address);
+      await middleman.connect(bob).setOperator(alice.address);
+      expect(await middleman.operatorAddress()).to.be.equal(alice.address);
+      await middleman.connect(alice).setOperator(guardian.address);
+      expect(await middleman.operatorAddress()).to.be.equal(guardian.address);
+      await expect(middleman.connect(alice).setOperator(alice.address)).to.be.revertedWith('Not owner or operator');
+    });
+  });
+  describe('setGauge', () => {
+    it('reverts - access control', async () => {
+      await expect(middleman.connect(alice).setGauge(ZERO_ADDRESS, angle.address, params)).to.be.revertedWith(
+        'Not owner or operator',
+      );
+      await middleman.connect(deployer).setOperator(alice.address);
+      expect(await middleman.operatorAddress()).to.be.equal(alice.address);
+      await middleman.connect(deployer).transferOwnership(bob.address);
+      expect(await middleman.owner()).to.be.equal(bob.address);
+      await expect(middleman.connect(deployer).setGauge(ZERO_ADDRESS, angle.address, params)).to.be.revertedWith(
+        'Not owner or operator',
+      );
+
+      const receipt = await (await middleman.connect(bob).setGauge(alice.address, angle.address, params)).wait();
+      inReceipt(receipt, 'GaugeSet', {
+        gauge: alice.address,
+      });
+      const receipt2 = await (await middleman.connect(bob).setGauge(bob.address, angle.address, params)).wait();
+      inReceipt(receipt2, 'GaugeSet', {
+        gauge: bob.address,
+      });
+    });
+    it('reverts - invalid params', async () => {
+      const params0 = {
+        uniV3Pool: pool.address,
+        rewardToken: agEUR,
+        positionWrappers: [alice.address, bob.address, deployer.address],
+        wrapperTypes: [0, 1, 2],
+        amount: parseEther('1'),
+        propToken0: 4000,
+        propToken1: 2000,
+        propFees: 4000,
+        isOutOfRangeIncentivized: 0,
+        epochStart: startTime,
+        numEpoch: 1,
+        boostedReward: 0,
+        boostingAddress: ZERO_ADDRESS,
+        rewardId: web3.utils.soliditySha3('TEST') as string,
+        additionalData: web3.utils.soliditySha3('test2ng') as string,
+      };
+      const params1 = {
+        uniV3Pool: alice.address,
+        rewardToken: angle.address,
+        positionWrappers: [alice.address, bob.address, deployer.address],
+        wrapperTypes: [0, 1, 2],
+        amount: parseEther('1'),
+        propToken0: 4000,
+        propToken1: 2000,
+        propFees: 4000,
+        isOutOfRangeIncentivized: 0,
+        epochStart: startTime,
+        numEpoch: 1,
+        boostedReward: 0,
+        boostingAddress: ZERO_ADDRESS,
+        rewardId: web3.utils.soliditySha3('TEST') as string,
+        additionalData: web3.utils.soliditySha3('test2ng') as string,
+      };
+      await expect(
+        middleman.connect(deployer).setGauge(ZERO_ADDRESS, angle.address, params),
+      ).to.be.revertedWithCustomError(middleman, 'InvalidParams');
+      await expect(
+        middleman.connect(deployer).setGauge(alice.address, ZERO_ADDRESS, params),
+      ).to.be.revertedWithCustomError(middleman, 'InvalidParams');
+      // Pool does not have valid tokens 0 and 1
+      await expect(middleman.connect(alice).setGauge(alice.address, angle.address, params)).to.be.reverted;
+      await expect(middleman.connect(guardian).setGauge(bob.address, angle.address, params1)).to.be.reverted;
+    });
+    it('success - value updated - token 0', async () => {
+      await pool.setToken(agEUR, 0);
+      const receipt = await (await middleman.connect(deployer).setGauge(alice.address, angle.address, params)).wait();
+      inReceipt(receipt, 'GaugeSet', {
+        gauge: alice.address,
+      });
+      const reward = await middleman.gaugeParams(alice.address, angle.address);
+      expect(reward.uniV3Pool).to.be.equal(pool.address);
+      expect(reward.rewardToken).to.be.equal(angle.address);
+      expect(reward.amount).to.be.equal(parseEther('1'));
+      expect(reward.propToken0).to.be.equal(4000);
+      expect(reward.propToken1).to.be.equal(2000);
+      expect(reward.propFees).to.be.equal(4000);
+      expect(reward.isOutOfRangeIncentivized).to.be.equal(0);
+      expect(reward.epochStart).to.be.equal(startTime);
+      expect(reward.numEpoch).to.be.equal(1);
+      expect(reward.boostedReward).to.be.equal(0);
+      expect(reward.boostingAddress).to.be.equal(ZERO_ADDRESS);
+      expect(reward.rewardId).to.be.equal(web3.utils.soliditySha3('TEST') as string);
+    });
+    it('success - value updated - token 1', async () => {
+      await pool.setToken(agEUR, 1);
+      const receipt = await (await middleman.connect(deployer).setGauge(alice.address, angle.address, params)).wait();
+      inReceipt(receipt, 'GaugeSet', {
+        gauge: alice.address,
+      });
+      const reward = await middleman.gaugeParams(alice.address, angle.address);
+      expect(reward.uniV3Pool).to.be.equal(pool.address);
+      expect(reward.rewardToken).to.be.equal(angle.address);
+      expect(reward.amount).to.be.equal(parseEther('1'));
+      expect(reward.propToken0).to.be.equal(4000);
+      expect(reward.propToken1).to.be.equal(2000);
+      expect(reward.propFees).to.be.equal(4000);
+      expect(reward.isOutOfRangeIncentivized).to.be.equal(0);
+      expect(reward.epochStart).to.be.equal(startTime);
+      expect(reward.numEpoch).to.be.equal(1);
+      expect(reward.boostedReward).to.be.equal(0);
+      expect(reward.boostingAddress).to.be.equal(ZERO_ADDRESS);
+      expect(reward.rewardId).to.be.equal(web3.utils.soliditySha3('TEST') as string);
+    });
+  });
+  describe('incentivizePool', () => {
+    it('reverts - invalid params', async () => {
+      await pool.setToken(agEUR, 1);
+      await middleman.connect(deployer).setGauge(alice.address, angle.address, params);
+      // No incentive token specified
+      await expect(
+        middleman
+          .connect(bob)
+          .incentivizePool(ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, 0, parseEther('0.5')),
+      ).to.be.reverted;
+      // No approval
+      await expect(
+        middleman
+          .connect(bob)
+          .incentivizePool(ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('0.5')),
+      ).to.be.reverted;
+      await expect(
+        middleman
+          .connect(alice)
+          .incentivizePool(ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('0.5')),
+      ).to.be.revertedWithCustomError(middleman, 'InvalidParams');
+    });
+    it('success - rewards well sent', async () => {
+      await pool.setToken(agEUR, 1);
+      await middleman.connect(deployer).setGauge(alice.address, angle.address, params);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('0.7'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(1);
+      expect(await angle.balanceOf(manager.address)).to.be.equal(parseEther('0'));
+      expect(await angle.balanceOf(bob.address)).to.be.equal(parseEther('0.7'));
+      expect(await angle.balanceOf(middleman.address)).to.be.equal(parseEther('0'));
+      expect(await angle.balanceOf(alice.address)).to.be.equal(parseEther('999.3'));
+      const reward = await manager.distributionList(0);
+      expect(reward.uniV3Pool).to.be.equal(pool.address);
+      expect(reward.rewardToken).to.be.equal(angle.address);
+      expect(reward.amount).to.be.equal(parseEther('0.7'));
+      expect(reward.propToken0).to.be.equal(4000);
+      expect(reward.propToken1).to.be.equal(2000);
+      expect(reward.propFees).to.be.equal(4000);
+      expect(reward.isOutOfRangeIncentivized).to.be.equal(0);
+      expect(reward.epochStart).to.be.equal(await pool.round(await latestTime()));
+      expect(reward.numEpoch).to.be.equal(1);
+      expect(reward.boostedReward).to.be.equal(0);
+      expect(reward.boostingAddress).to.be.equal(ZERO_ADDRESS);
+      const rewardId = solidityKeccak256(['address', 'uint256'], [middleman.address, 0]);
+      expect(reward.rewardId).to.be.equal(rewardId);
+      expect(await angle.allowance(middleman.address, manager.address)).to.be.equal(0);
+    });
+    it('success - rewards well sent - when gauge not whitelisted but tx origin is', async () => {
+      await pool.setToken(agEUR, 1);
+      await middleman.connect(deployer).setGauge(alice.address, angle.address, params);
+      await manager.connect(guardian).toggleSigningWhitelist(middleman.address);
+      expect(await manager.userSignatureWhitelist(middleman.address)).to.be.equal(0);
+      await manager.connect(guardian).setMessage('hello');
+
+      await expect(
+        middleman
+          .connect(alice)
+          .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('0.7')),
+      ).to.be.revertedWithCustomError(manager, 'NotSigned');
+
+      await manager.connect(guardian).toggleSigningWhitelist(alice.address);
+      expect(await manager.userSignatureWhitelist(alice.address)).to.be.equal(1);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('0.7'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(1);
+      expect(await angle.balanceOf(manager.address)).to.be.equal(parseEther('0'));
+      expect(await angle.balanceOf(bob.address)).to.be.equal(parseEther('0.7'));
+      expect(await angle.balanceOf(middleman.address)).to.be.equal(parseEther('0'));
+      expect(await angle.balanceOf(alice.address)).to.be.equal(parseEther('999.3'));
+      const reward = await manager.distributionList(0);
+      expect(reward.uniV3Pool).to.be.equal(pool.address);
+      expect(reward.rewardToken).to.be.equal(angle.address);
+      expect(reward.amount).to.be.equal(parseEther('0.7'));
+      expect(reward.propToken0).to.be.equal(4000);
+      expect(reward.propToken1).to.be.equal(2000);
+      expect(reward.propFees).to.be.equal(4000);
+      expect(reward.isOutOfRangeIncentivized).to.be.equal(0);
+      expect(reward.epochStart).to.be.equal(await pool.round(await latestTime()));
+      expect(reward.numEpoch).to.be.equal(1);
+      expect(reward.boostedReward).to.be.equal(0);
+      expect(reward.boostingAddress).to.be.equal(ZERO_ADDRESS);
+      const rewardId = solidityKeccak256(['address', 'uint256'], [middleman.address, 0]);
+      expect(reward.rewardId).to.be.equal(rewardId);
+    });
+    it('success - rewards well sent when zero amount', async () => {
+      await pool.setToken(agEUR, 1);
+      await middleman.connect(deployer).setGauge(alice.address, angle.address, params);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('0'));
+      expect(await angle.balanceOf(alice.address)).to.be.equal(parseEther('1000'));
+      expect(await angle.balanceOf(middleman.address)).to.be.equal(parseEther('0'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(0);
+      expect(await angle.balanceOf(manager.address)).to.be.equal(parseEther('0'));
+      expect(await angle.balanceOf(bob.address)).to.be.equal(parseEther('0'));
+    });
+    it('success - rewards kept when inferior to min distribution amount and then re-used', async () => {
+      await pool.setToken(agEUR, 1);
+      await middleman.connect(deployer).setGauge(alice.address, angle.address, params);
+      await manager.connect(guardian).setRewardTokenMinAmounts([angle.address], [parseEther('10')]);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('5'));
+      expect(await angle.balanceOf(middleman.address)).to.be.equal(parseEther('5'));
+      expect(await middleman.leftovers(angle.address, alice.address)).to.be.equal(parseEther('5'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(0);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('2'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(0);
+      expect(await middleman.leftovers(angle.address, alice.address)).to.be.equal(parseEther('7'));
+      expect(await angle.balanceOf(middleman.address)).to.be.equal(parseEther('7'));
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('4'));
+      expect(await middleman.leftovers(angle.address, alice.address)).to.be.equal(parseEther('0'));
+      expect(await angle.balanceOf(alice.address)).to.be.equal(parseEther('989'));
+      const reward = await manager.distributionList(0);
+      expect(reward.uniV3Pool).to.be.equal(pool.address);
+      expect(reward.rewardToken).to.be.equal(angle.address);
+      expect(reward.amount).to.be.equal(parseEther('11'));
+      expect(reward.propToken0).to.be.equal(4000);
+      expect(reward.propToken1).to.be.equal(2000);
+      expect(reward.propFees).to.be.equal(4000);
+      expect(reward.isOutOfRangeIncentivized).to.be.equal(0);
+      expect(reward.epochStart).to.be.equal(await pool.round(await latestTime()));
+      expect(reward.numEpoch).to.be.equal(1);
+      expect(reward.boostedReward).to.be.equal(0);
+      expect(reward.boostingAddress).to.be.equal(ZERO_ADDRESS);
+      const rewardId = solidityKeccak256(['address', 'uint256'], [middleman.address, 0]);
+      expect(reward.rewardId).to.be.equal(rewardId);
+
+      const params2 = {
+        uniV3Pool: pool.address,
+        rewardToken: angle.address,
+        positionWrappers: [alice.address, bob.address, deployer.address],
+        wrapperTypes: [0, 1, 2],
+        amount: parseEther('1'),
+        propToken0: 4000,
+        propToken1: 2000,
+        propFees: 4000,
+        isOutOfRangeIncentivized: 0,
+        epochStart: startTime,
+        numEpoch: 2,
+        boostedReward: 0,
+        boostingAddress: ZERO_ADDRESS,
+        rewardId: web3.utils.soliditySha3('TEST') as string,
+        additionalData: web3.utils.soliditySha3('test2ng') as string,
+      };
+      await middleman.connect(deployer).setGauge(alice.address, angle.address, params2);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('11'));
+      expect(await middleman.leftovers(angle.address, alice.address)).to.be.equal(parseEther('11'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(1);
+      await middleman
+        .connect(alice)
+        .incentivizePool(alice.address, ZERO_ADDRESS, ZERO_ADDRESS, angle.address, 0, parseEther('12'));
+      expect(await middleman.leftovers(angle.address, alice.address)).to.be.equal(parseEther('0'));
+      expect(await manager.nonces(middleman.address)).to.be.equal(2);
+      const reward2 = await manager.distributionList(1);
+      expect(reward2.uniV3Pool).to.be.equal(pool.address);
+      expect(reward2.rewardToken).to.be.equal(angle.address);
+      expect(reward2.amount).to.be.equal(parseEther('23'));
+      expect(reward2.propToken0).to.be.equal(4000);
+      expect(reward2.propToken1).to.be.equal(2000);
+      expect(reward2.propFees).to.be.equal(4000);
+      expect(reward2.isOutOfRangeIncentivized).to.be.equal(0);
+      expect(reward2.epochStart).to.be.equal(await pool.round(await latestTime()));
+      expect(reward2.numEpoch).to.be.equal(2);
+      expect(reward2.boostedReward).to.be.equal(0);
+      expect(reward2.boostingAddress).to.be.equal(ZERO_ADDRESS);
+      const rewardId2 = solidityKeccak256(['address', 'uint256'], [middleman.address, 1]);
+      expect(reward2.rewardId).to.be.equal(rewardId2);
+    });
+  });
+});
diff --git a/yarn.lock b/yarn.lock
index ae821b1..4a7423d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7,11 +7,12 @@
   resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf"
   integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
 
-"@angleprotocol/sdk@3.0.87":
-  version "3.0.87"
-  resolved "https://registry.yarnpkg.com/@angleprotocol/sdk/-/sdk-3.0.87.tgz#20fdbb6b146dce0cb2a8fa37ade4c02a22fc3d0a"
-  integrity sha512-CFNbZJY96YL00OO0VjJONLU1bWF5tzn3BXxAhImBWMPsYGar9D/Jl/EABYhpok/WZI4gTqXNGJO7hQlF9d85Bg==
+"@angleprotocol/sdk@0.21.1":
+  version "0.21.1"
+  resolved "https://npm.pkg.github.com/download/@angleprotocol/sdk/0.21.1/2f785e40f44da487d3af00dd4234e1aa5222fc46#2f785e40f44da487d3af00dd4234e1aa5222fc46"
+  integrity sha512-/4G2AL+ccDgL4DOUzSGp7c3yKLoWBy7+hav4/Tpkdo283MB9RSW4k84jJQov+OH3p5to3j5SBRfwrhND5zwu6Q==
   dependencies:
+    "@apollo/client" "^3.7.17"
     "@typechain/ethers-v5" "^10.0.0"
     "@types/lodash" "^4.14.180"
     ethers "^5.6.4"
@@ -20,10 +21,28 @@
     jsbi "^4.3.0"
     keccak256 "^1.0.6"
     lodash "^4.17.21"
-    merkletreejs "^0.3.9"
+    merkletreejs "^0.3.10"
     tiny-invariant "^1.1.0"
     typechain "^8.0.0"
 
+"@apollo/client@^3.7.17":
+  version "3.8.9"
+  resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.8.9.tgz#0e4ac133eb04c63e618138c1ebf273d9f110a4d0"
+  integrity sha512-IcQDFEEPc9+PEQsxhxQvsoQ04BRarOzi/Ila5PcniRSDeKJWgY22dnp6+V1i1fWXRDVd1ybdvze4sFESDVQUCQ==
+  dependencies:
+    "@graphql-typed-document-node/core" "^3.1.1"
+    "@wry/equality" "^0.5.6"
+    "@wry/trie" "^0.5.0"
+    graphql-tag "^2.12.6"
+    hoist-non-react-statics "^3.3.2"
+    optimism "^0.18.0"
+    prop-types "^15.7.2"
+    response-iterator "^0.2.6"
+    symbol-observable "^4.0.0"
+    ts-invariant "^0.10.3"
+    tslib "^2.3.0"
+    zen-observable-ts "^1.2.5"
+
 "@babel/code-frame@^7.0.0":
   version "7.16.7"
   resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz"
@@ -52,6 +71,42 @@
   dependencies:
     regenerator-runtime "^0.13.4"
 
+"@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"
+
 "@ensdomains/address-encoder@^0.1.7":
   version "0.1.9"
   resolved "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz"
@@ -806,6 +861,32 @@
     bech32 "1.1.4"
     ws "7.4.6"
 
+"@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.5.1", "@ethersproject/random@^5.5.0":
   version "5.5.1"
   resolved "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz"
@@ -1181,6 +1262,11 @@
     "@ethersproject/properties" "^5.7.0"
     "@ethersproject/strings" "^5.7.0"
 
+"@graphql-typed-document-node/core@^3.1.1":
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861"
+  integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==
+
 "@humanwhocodes/config-array@^0.11.13":
   version "0.11.13"
   resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297"
@@ -1242,29 +1328,31 @@
     "@nodelib/fs.scandir" "2.1.5"
     fastq "^1.6.0"
 
-"@nomicfoundation/ethereumjs-block@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz"
-  integrity sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==
-  dependencies:
-    "@nomicfoundation/ethereumjs-common" "^3.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-trie" "^5.0.0"
-    "@nomicfoundation/ethereumjs-tx" "^4.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
+"@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@^6.0.0":
-  version "6.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz"
-  integrity sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==
-  dependencies:
-    "@nomicfoundation/ethereumjs-block" "^4.0.0"
-    "@nomicfoundation/ethereumjs-common" "^3.0.0"
-    "@nomicfoundation/ethereumjs-ethash" "^2.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-trie" "^5.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
+"@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"
@@ -1272,105 +1360,105 @@
     lru-cache "^5.1.1"
     memory-level "^1.0.0"
 
-"@nomicfoundation/ethereumjs-common@^3.0.0":
-  version "3.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz"
-  integrity sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==
+"@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" "^8.0.0"
+    "@nomicfoundation/ethereumjs-util" "9.0.2"
     crc-32 "^1.2.0"
 
-"@nomicfoundation/ethereumjs-ethash@^2.0.0":
-  version "2.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz"
-  integrity sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==
+"@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" "^4.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
+    "@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@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz"
-  integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==
+"@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:
-    "@nomicfoundation/ethereumjs-common" "^3.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
-    "@types/async-eventemitter" "^0.2.1"
-    async-eventemitter "^0.2.4"
+    "@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@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2":
-  version "4.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz"
-  integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==
+"@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@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz"
-  integrity sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==
+"@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" "^3.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-trie" "^5.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
+    "@nomicfoundation/ethereumjs-common" "4.0.2"
+    "@nomicfoundation/ethereumjs-rlp" "5.0.2"
     debug "^4.3.3"
     ethereum-cryptography "0.1.3"
-    functional-red-black-tree "^1.0.1"
+    ethers "^5.7.1"
+    js-sdsl "^4.1.4"
 
-"@nomicfoundation/ethereumjs-trie@^5.0.0":
-  version "5.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz"
-  integrity sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==
+"@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" "^4.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
+    "@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@^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz"
-  integrity sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==
-  dependencies:
-    "@nomicfoundation/ethereumjs-common" "^3.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
+"@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@^8.0.0":
-  version "8.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz"
-  integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==
+"@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:
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2"
+    "@chainsafe/ssz" "^0.10.0"
+    "@nomicfoundation/ethereumjs-rlp" "5.0.2"
     ethereum-cryptography "0.1.3"
 
-"@nomicfoundation/ethereumjs-vm@^6.0.0":
-  version "6.0.0"
-  resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz"
-  integrity sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==
-  dependencies:
-    "@nomicfoundation/ethereumjs-block" "^4.0.0"
-    "@nomicfoundation/ethereumjs-blockchain" "^6.0.0"
-    "@nomicfoundation/ethereumjs-common" "^3.0.0"
-    "@nomicfoundation/ethereumjs-evm" "^1.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-statemanager" "^1.0.0"
-    "@nomicfoundation/ethereumjs-trie" "^5.0.0"
-    "@nomicfoundation/ethereumjs-tx" "^4.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
-    "@types/async-eventemitter" "^0.2.1"
-    async-eventemitter "^0.2.4"
+"@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"
-    functional-red-black-tree "^1.0.1"
     mcl-wasm "^0.7.1"
     rustbn.js "~0.2.0"
 
@@ -1983,11 +2071,6 @@
   dependencies:
     fs-extra "^9.1.0"
 
-"@types/async-eventemitter@^0.2.1":
-  version "0.2.1"
-  resolved "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz"
-  integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==
-
 "@types/bignumber.js@^5.0.0":
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969"
@@ -2137,6 +2220,14 @@
   resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz"
   integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
 
+"@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/responselike@*", "@types/responselike@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
@@ -2262,6 +2353,41 @@
   resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
   integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
 
+"@wry/caches@^1.0.0":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@wry/caches/-/caches-1.0.1.tgz#8641fd3b6e09230b86ce8b93558d44cf1ece7e52"
+  integrity sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==
+  dependencies:
+    tslib "^2.3.0"
+
+"@wry/context@^0.7.0":
+  version "0.7.4"
+  resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.7.4.tgz#e32d750fa075955c4ab2cfb8c48095e1d42d5990"
+  integrity sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==
+  dependencies:
+    tslib "^2.3.0"
+
+"@wry/equality@^0.5.6":
+  version "0.5.7"
+  resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.7.tgz#72ec1a73760943d439d56b7b1e9985aec5d497bb"
+  integrity sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==
+  dependencies:
+    tslib "^2.3.0"
+
+"@wry/trie@^0.4.3":
+  version "0.4.3"
+  resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.4.3.tgz#077d52c22365871bf3ffcbab8e95cb8bc5689af4"
+  integrity sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==
+  dependencies:
+    tslib "^2.3.0"
+
+"@wry/trie@^0.5.0":
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.5.0.tgz#11e783f3a53f6e4cd1d42d2d1323f5bc3fa99c94"
+  integrity sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==
+  dependencies:
+    tslib "^2.3.0"
+
 JSONStream@1.3.2:
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea"
@@ -2280,13 +2406,6 @@ abbrev@1.0.x:
   resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
   integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==
 
-abort-controller@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz"
-  integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
-  dependencies:
-    event-target-shim "^5.0.0"
-
 abortcontroller-polyfill@^1.7.3:
   version "1.7.5"
   resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed"
@@ -2629,13 +2748,6 @@ astral-regex@^2.0.0:
   resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz"
   integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
 
-async-eventemitter@^0.2.4:
-  version "0.2.4"
-  resolved "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz"
-  integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==
-  dependencies:
-    async "^2.4.0"
-
 async-limiter@~1.0.0:
   version "1.0.1"
   resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz"
@@ -2646,13 +2758,6 @@ async@1.x:
   resolved "https://registry.npmjs.org/async/-/async-1.5.2.tgz"
   integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==
 
-async@^2.4.0:
-  version "2.6.3"
-  resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz"
-  integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
-  dependencies:
-    lodash "^4.17.14"
-
 asynckit@^0.4.0:
   version "0.4.0"
   resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
@@ -3128,6 +3233,11 @@ camelcase@^6.0.0:
   resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
   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==
+
 caseless@^0.12.0, caseless@~0.12.0:
   version "0.12.0"
   resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
@@ -3712,6 +3822,11 @@ crypto-js@^3.1.9-1:
   resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b"
   integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==
 
+crypto-js@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
+  integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==
+
 css-select@^4.1.3:
   version "4.2.1"
   resolved "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz"
@@ -4935,11 +5050,6 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6:
     is-hex-prefixed "1.0.0"
     strip-hex-prefix "1.0.0"
 
-event-target-shim@^5.0.0:
-  version "5.0.1"
-  resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
-  integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
-
 eventemitter3@4.0.4:
   version "4.0.4"
   resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz"
@@ -5772,6 +5882,13 @@ graphql-request@^3.6.1:
     extract-files "^9.0.0"
     form-data "^3.0.0"
 
+graphql-tag@^2.12.6:
+  version "2.12.6"
+  resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1"
+  integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==
+  dependencies:
+    tslib "^2.1.0"
+
 graphql@^15.7.1:
   version "15.8.0"
   resolved "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz"
@@ -5853,28 +5970,27 @@ hardhat-spdx-license-identifier@2.0.3:
   resolved "https://registry.npmjs.org/hardhat-spdx-license-identifier/-/hardhat-spdx-license-identifier-2.0.3.tgz"
   integrity sha512-G4u4I1md0tWaitX6Os7Nq9sYZ/CFdR+ibm7clCksGJ4yrtdHEZxgLjWpJ0WiALF9SoFKt03PwCe9lczDQ/5ADA==
 
-hardhat@^2.12.6:
-  version "2.12.6"
-  resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.6.tgz#ea3c058bbd81850867389d10f76037cfa52a0019"
-  integrity sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA==
+hardhat@^2.19.0:
+  version "2.19.0"
+  resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.0.tgz#1e08658863550ba351788ea128e544ff80584a31"
+  integrity sha512-kMpwovOEfrFRQXEopCP+JTcKVwSYVj8rnXE0LynxDqnh06yvyKCQknmXL6IVYTHQL6Csysc/yNbCHQbjSeJGpA==
   dependencies:
     "@ethersproject/abi" "^5.1.2"
     "@metamask/eth-sig-util" "^4.0.0"
-    "@nomicfoundation/ethereumjs-block" "^4.0.0"
-    "@nomicfoundation/ethereumjs-blockchain" "^6.0.0"
-    "@nomicfoundation/ethereumjs-common" "^3.0.0"
-    "@nomicfoundation/ethereumjs-evm" "^1.0.0"
-    "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
-    "@nomicfoundation/ethereumjs-statemanager" "^1.0.0"
-    "@nomicfoundation/ethereumjs-trie" "^5.0.0"
-    "@nomicfoundation/ethereumjs-tx" "^4.0.0"
-    "@nomicfoundation/ethereumjs-util" "^8.0.0"
-    "@nomicfoundation/ethereumjs-vm" "^6.0.0"
+    "@nomicfoundation/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"
-    abort-controller "^3.0.0"
     adm-zip "^0.4.16"
     aggregate-error "^3.0.0"
     ansi-escapes "^4.3.0"
@@ -5897,7 +6013,6 @@ hardhat@^2.12.6:
     mnemonist "^0.38.0"
     mocha "^10.0.0"
     p-map "^4.0.0"
-    qs "^6.7.0"
     raw-body "^2.4.1"
     resolve "1.17.0"
     semver "^6.3.0"
@@ -6056,6 +6171,13 @@ hmac-drbg@^1.0.1:
     minimalistic-assert "^1.0.0"
     minimalistic-crypto-utils "^1.0.1"
 
+hoist-non-react-statics@^3.3.2:
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+  integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+  dependencies:
+    react-is "^16.7.0"
+
 hosted-git-info@^2.1.4:
   version "2.8.9"
   resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz"
@@ -6598,6 +6720,11 @@ isurl@^1.0.0-alpha5:
     has-to-string-tag-x "^1.2.0"
     is-object "^1.0.1"
 
+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.5.5:
   version "0.5.5"
   resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz"
@@ -6613,9 +6740,9 @@ js-sha3@0.8.0, js-sha3@^0.8.0:
   resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz"
   integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
 
-js-tokens@^4.0.0:
+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
   version "4.0.0"
-  resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
+  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
   integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
 
 js-yaml@3.13.1:
@@ -6945,6 +7072,13 @@ log-symbols@4.1.0:
     chalk "^4.1.0"
     is-unicode-supported "^0.1.0"
 
+loose-envify@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+  integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+  dependencies:
+    js-tokens "^3.0.0 || ^4.0.0"
+
 loupe@^2.3.1:
   version "2.3.4"
   resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz"
@@ -7067,14 +7201,14 @@ merkletreejs@0.2.32:
     treeify "^1.1.0"
     web3-utils "^1.3.4"
 
-merkletreejs@^0.3.9:
-  version "0.3.9"
-  resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.3.9.tgz#cdb364a3b974a44f4eff3446522d7066e0cf95de"
-  integrity sha512-NjlATjJr4NEn9s8v/VEHhgwRWaE1eA/Une07d9SEqKzULJi1Wsh0Y3svwJdP2bYLMmgSBHzOrNydMWM1NN9VeQ==
+merkletreejs@^0.3.10:
+  version "0.3.11"
+  resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.3.11.tgz#e0de05c3ca1fd368de05a12cb8efb954ef6fc04f"
+  integrity sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==
   dependencies:
     bignumber.js "^9.0.1"
     buffer-reverse "^1.0.1"
-    crypto-js "^3.1.9-1"
+    crypto-js "^4.2.0"
     treeify "^1.1.0"
     web3-utils "^1.3.4"
 
@@ -7731,6 +7865,16 @@ onetime@^2.0.0:
   dependencies:
     mimic-fn "^1.0.0"
 
+optimism@^0.18.0:
+  version "0.18.0"
+  resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.18.0.tgz#e7bb38b24715f3fdad8a9a7fc18e999144bbfa63"
+  integrity sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==
+  dependencies:
+    "@wry/caches" "^1.0.0"
+    "@wry/context" "^0.7.0"
+    "@wry/trie" "^0.4.3"
+    tslib "^2.3.0"
+
 optionator@^0.8.1, optionator@^0.8.2:
   version "0.8.3"
   resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz"
@@ -8154,6 +8298,15 @@ promise@^8.0.0:
   dependencies:
     asap "~2.0.6"
 
+prop-types@^15.7.2:
+  version "15.8.1"
+  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+  integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+  dependencies:
+    loose-envify "^1.4.0"
+    object-assign "^4.1.1"
+    react-is "^16.13.1"
+
 proper-lockfile@^4.1.1:
   version "4.1.2"
   resolved "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz"
@@ -8229,7 +8382,7 @@ qs@6.9.7:
   resolved "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz"
   integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
 
-qs@^6.4.0, qs@^6.7.0, qs@^6.9.4:
+qs@^6.4.0, qs@^6.9.4:
   version "6.10.3"
   resolved "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz"
   integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
@@ -8305,6 +8458,11 @@ raw-body@^2.4.1:
     iconv-lite "0.4.24"
     unpipe "1.0.0"
 
+react-is@^16.13.1, react-is@^16.7.0:
+  version "16.13.1"
+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
 read-pkg-up@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz"
@@ -8556,6 +8714,11 @@ resolve@^1.22.2, resolve@^1.22.4:
     path-parse "^1.0.7"
     supports-preserve-symlinks-flag "^1.0.0"
 
+response-iterator@^0.2.6:
+  version "0.2.6"
+  resolved "https://registry.yarnpkg.com/response-iterator/-/response-iterator-0.2.6.tgz#249005fb14d2e4eeb478a3f735a28fd8b4c9f3da"
+  integrity sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==
+
 responselike@^1.0.2:
   version "1.0.2"
   resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz"
@@ -9451,6 +9614,11 @@ swarm-js@^0.1.40:
     tar "^4.0.2"
     xhr-request "^1.0.1"
 
+symbol-observable@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"
+  integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==
+
 sync-request@^6.0.0:
   version "6.1.0"
   resolved "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz"
@@ -9671,6 +9839,13 @@ ts-essentials@^7.0.1:
   resolved "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz"
   integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==
 
+ts-invariant@^0.10.3:
+  version "0.10.3"
+  resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c"
+  integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==
+  dependencies:
+    tslib "^2.1.0"
+
 ts-node@10.1.0:
   version "10.1.0"
   resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz"
@@ -9702,6 +9877,11 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
   resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
 
+tslib@^2.1.0, tslib@^2.3.0:
+  version "2.6.2"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
+  integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
+
 tslib@^2.2.0:
   version "2.3.1"
   resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz"
@@ -11366,6 +11546,18 @@ yocto-queue@^0.1.0:
   resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
 
+zen-observable-ts@^1.2.5:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58"
+  integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==
+  dependencies:
+    zen-observable "0.8.15"
+
+zen-observable@0.8.15:
+  version "0.8.15"
+  resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
+  integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
+
 zksync-web3@^0.8.1:
   version "0.8.1"
   resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.8.1.tgz#db289d8f6caf61f4d5ddc471fa3448d93208dc14"