From 9a4af052f414edd31280cf55d3524d4185b0a009 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Wed, 5 Apr 2023 17:49:28 -0400 Subject: [PATCH 01/25] Remove Forwarder (#160) --- .../contracts/forwarder/Forwarder.sol | 68 --------- .../contracts/interfaces/IForwarder.sol | 20 --- .../perennial/deploy/004_deploy_forwarder.ts | 47 ------ ...iinvoker.ts => 004_deploy_multiinvoker.ts} | 0 .../integration/forwarder/forwarder.test.ts | 36 ----- .../test/integration/helpers/setupHelpers.ts | 11 -- .../test/unit/forwarder/Forwarder.test.ts | 134 ------------------ .../mainnet/core/verifyCore.test.ts | 12 -- 8 files changed, 328 deletions(-) delete mode 100644 packages/perennial/contracts/forwarder/Forwarder.sol delete mode 100644 packages/perennial/contracts/interfaces/IForwarder.sol delete mode 100644 packages/perennial/deploy/004_deploy_forwarder.ts rename packages/perennial/deploy/{005_deploy_multiinvoker.ts => 004_deploy_multiinvoker.ts} (100%) delete mode 100644 packages/perennial/test/integration/forwarder/forwarder.test.ts delete mode 100644 packages/perennial/test/unit/forwarder/Forwarder.test.ts diff --git a/packages/perennial/contracts/forwarder/Forwarder.sol b/packages/perennial/contracts/forwarder/Forwarder.sol deleted file mode 100644 index 17789167..00000000 --- a/packages/perennial/contracts/forwarder/Forwarder.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; - -import "../interfaces/IForwarder.sol"; - -/** - * @title Forwarder - * @notice Facilitates collateral deposits to the protocol where the amount is supplied - * in USDC then wrapped as DSU before being deposited. - */ -contract Forwarder is IForwarder { - // @dev USDC stablecoin - Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase - - // @dev DSU stablecoin - Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase - - /// @dev Contract that wraps USDC to DSU - IBatcher public immutable batcher; - - /// @dev Contract managing state for collateral accounts in the protocol - ICollateral public immutable collateral; - - /** - * @notice Initializes the contract state - * @param usdc_ The USDC token contract address - * @param dsu_ The DSU token contract address - * @param batcher_ The USDC-to-DSU batcher contract address - * @param collateral_ The perennial collateral contract address - */ - constructor( - Token6 usdc_, - Token18 dsu_, - IBatcher batcher_, - ICollateral collateral_ - ) { - if (!Address.isContract(Token6.unwrap(usdc_))) revert ForwarderNotContractAddressError(); - if (!Address.isContract(Token18.unwrap(dsu_))) revert ForwarderNotContractAddressError(); - if (!Address.isContract(address(batcher_))) revert ForwarderNotContractAddressError(); - if (!Address.isContract(address(collateral_))) revert ForwarderNotContractAddressError(); - - USDC = usdc_; - DSU = dsu_; - batcher = batcher_; - collateral = collateral_; - - USDC.approve(address(batcher)); - DSU.approve(address(collateral)); - } - - /** - * @notice Pulls `amount` of USDC from `msg.sender`'s balance, wraps it as DSU, - and deposits it as collateral to `account`'s `product` account - * @param account Account to deposit the collateral for - * @param product Product to credit the collateral to - * @param amount 18 decimals-normalized stablecoin (USDC, DSU) value of collateral to deposit - */ - function wrapAndDeposit( - address account, - IProduct product, - UFixed18 amount - ) external { - USDC.pull(msg.sender, amount, true); - batcher.wrap(amount, address(this)); - collateral.depositTo(account, product, amount); - emit WrapAndDeposit(account, product, amount); - } -} diff --git a/packages/perennial/contracts/interfaces/IForwarder.sol b/packages/perennial/contracts/interfaces/IForwarder.sol deleted file mode 100644 index a9a0d479..00000000 --- a/packages/perennial/contracts/interfaces/IForwarder.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.13; - -import "@equilibria/root/token/types/Token18.sol"; -import "@equilibria/root/token/types/Token6.sol"; -import "@equilibria/root/number/types/UFixed18.sol"; -import "@equilibria/emptyset-batcher/interfaces/IBatcher.sol"; -import "./ICollateral.sol"; - -interface IForwarder { - error ForwarderNotContractAddressError(); - - event WrapAndDeposit(address indexed account, IProduct indexed product, UFixed18 amount); - - function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase - function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase - function batcher() external view returns (IBatcher); - function collateral() external view returns (ICollateral); - function wrapAndDeposit(address account, IProduct product, UFixed18 amount) external; -} diff --git a/packages/perennial/deploy/004_deploy_forwarder.ts b/packages/perennial/deploy/004_deploy_forwarder.ts deleted file mode 100644 index 31753654..00000000 --- a/packages/perennial/deploy/004_deploy_forwarder.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' -import { Collateral, Collateral__factory } from '../types/generated' -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' - -const FORWARDER_DEPRECATED = true - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - if (FORWARDER_DEPRECATED) { - console.log('Forwarder marked as deprecated, skipping deploy') - return - } - - const { deployments, getNamedAccounts, ethers } = hre - const { deploy, get, getOrNull } = deployments - const { deployer } = await getNamedAccounts() - const deployerSigner: SignerWithAddress = await ethers.getSigner(deployer) - - // NETWORK CONSTANTS - const dsuAddress = (await getOrNull('DSU'))?.address || (await get('TestnetDSU')).address - const usdcAddress = (await getOrNull('USDC'))?.address || (await get('TestnetUSDC')).address - const batcherAddress = (await getOrNull('Batcher'))?.address || (await getOrNull('TestnetBatcher'))?.address - if (!batcherAddress) { - console.log('Batcher not found. Skipping Forwarder deploy') - return - } - - const collateral: Collateral = new Collateral__factory(deployerSigner).attach((await get('Collateral_Proxy')).address) - - console.log('using DSU address: ' + dsuAddress) - console.log('using USDC address: ' + usdcAddress) - console.log('using batcher address: ' + batcherAddress) - console.log('using collateral at ' + collateral.address) - - // FORWARDER - await deploy('Forwarder', { - contract: 'Forwarder', - args: [usdcAddress, dsuAddress, batcherAddress, collateral.address], - from: deployer, - skipIfAlreadyDeployed: true, - log: true, - autoMine: true, - }) -} - -export default func -func.tags = ['Forwarder'] diff --git a/packages/perennial/deploy/005_deploy_multiinvoker.ts b/packages/perennial/deploy/004_deploy_multiinvoker.ts similarity index 100% rename from packages/perennial/deploy/005_deploy_multiinvoker.ts rename to packages/perennial/deploy/004_deploy_multiinvoker.ts diff --git a/packages/perennial/test/integration/forwarder/forwarder.test.ts b/packages/perennial/test/integration/forwarder/forwarder.test.ts deleted file mode 100644 index b2f6152d..00000000 --- a/packages/perennial/test/integration/forwarder/forwarder.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { expect } from 'chai' -import { BigNumber, utils } from 'ethers' -import 'hardhat' - -import { InstanceVars, deployProtocol, createProduct } from '../helpers/setupHelpers' - -describe('Forwarder', () => { - let instanceVars: InstanceVars - - beforeEach(async () => { - instanceVars = await deployProtocol() - }) - - it('deposits the USDC amount wrapped as DSU to the product account', async () => { - const { user, userB, collateral, forwarder, dsu, usdc, usdcHolder } = instanceVars - - const product = await createProduct(instanceVars) - await usdc.connect(usdcHolder).transfer(user.address, 10e12) - - await usdc.connect(user).approve(forwarder.address, 10e12) - - await expect(forwarder.connect(user).wrapAndDeposit(userB.address, product.address, utils.parseEther('1000'))) - .to.emit(forwarder, 'WrapAndDeposit') - .withArgs(userB.address, product.address, utils.parseEther('1000')) - - expect(await usdc.balanceOf(user.address)).to.equal(BigNumber.from(10e12).sub(1000e6)) - - expect(await collateral['collateral(address,address)'](userB.address, product.address)).to.equal( - utils.parseEther('1000'), - ) - expect(await collateral['collateral(address)'](product.address)).to.equal(utils.parseEther('1000')) - - expect(await usdc.balanceOf(forwarder.address)).to.equal(0) - expect(await dsu.balanceOf(forwarder.address)).to.equal(0) - }) -}) diff --git a/packages/perennial/test/integration/helpers/setupHelpers.ts b/packages/perennial/test/integration/helpers/setupHelpers.ts index cf3da64c..9d3b29b2 100644 --- a/packages/perennial/test/integration/helpers/setupHelpers.ts +++ b/packages/perennial/test/integration/helpers/setupHelpers.ts @@ -23,8 +23,6 @@ import { UpgradeableBeacon__factory, PerennialLens, PerennialLens__factory, - Forwarder, - Forwarder__factory, Batcher, Batcher__factory, ERC20PresetMinterPauser, @@ -80,7 +78,6 @@ export interface InstanceVars { lens: PerennialLens batcher: Batcher reserve: IEmptySetReserve - forwarder: Forwarder incentiveToken: ERC20PresetMinterPauser } @@ -174,13 +171,6 @@ export async function deployProtocol(): Promise { const lens = await new PerennialLens__factory(owner).deploy(controller.address) - const forwarder = await new Forwarder__factory(owner).deploy( - usdc.address, - dsu.address, - batcher.address, - collateral.address, - ) - const incentiveToken = await new ERC20PresetMinterPauser__factory(owner).deploy('Incentive Token', 'ITKN') return { @@ -209,7 +199,6 @@ export async function deployProtocol(): Promise { lens, batcher, reserve, - forwarder, incentiveToken, } } diff --git a/packages/perennial/test/unit/forwarder/Forwarder.test.ts b/packages/perennial/test/unit/forwarder/Forwarder.test.ts deleted file mode 100644 index ec6c2225..00000000 --- a/packages/perennial/test/unit/forwarder/Forwarder.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { FakeContract, smock } from '@defi-wonderland/smock' -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { nextContractAddress } from '../../../../common/testutil/contract' -import { expect, use } from 'chai' -import { utils } from 'ethers' -import HRE from 'hardhat' - -import { - IBatcher, - ICollateral, - IProduct, - Forwarder, - Forwarder__factory, - IERC20Metadata, -} from '../../../types/generated' -import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' - -const { ethers } = HRE -use(smock.matchers) - -describe('Forwarder', () => { - let owner: SignerWithAddress - let user: SignerWithAddress - let account: SignerWithAddress - let collateral: FakeContract - let product: FakeContract - let batcher: FakeContract - let usdc: FakeContract - let dsu: FakeContract - let forwarder: Forwarder - - const forwarderFixture = async () => { - ;[owner, user, account] = await ethers.getSigners() - } - - beforeEach(async () => { - await loadFixture(forwarderFixture) - - collateral = await smock.fake('ICollateral') - product = await smock.fake('IProduct') - batcher = await smock.fake('IBatcher') - usdc = await smock.fake('IERC20Metadata') - dsu = await smock.fake('IERC20Metadata') - - const forwarderAddress = nextContractAddress(owner, 4) - usdc.allowance.whenCalledWith(forwarderAddress, batcher.address).returns(0) - usdc.approve.whenCalledWith(batcher.address, ethers.constants.MaxUint256).returns(true) - dsu.allowance.whenCalledWith(forwarderAddress, batcher.address).returns(0) - dsu.approve.whenCalledWith(collateral.address, ethers.constants.MaxUint256).returns(true) - - forwarder = await new Forwarder__factory(owner).deploy( - usdc.address, - dsu.address, - batcher.address, - collateral.address, - ) - }) - - describe('#constructor', () => { - it('constructs correctly', async () => { - expect(await forwarder.USDC()).to.equal(usdc.address) - expect(await forwarder.DSU()).to.equal(dsu.address) - expect(await forwarder.batcher()).to.equal(batcher.address) - expect(await forwarder.collateral()).to.equal(collateral.address) - }) - - it('reverts on invalid addresses', async () => { - await expect( - new Forwarder__factory(owner).deploy(user.address, dsu.address, batcher.address, collateral.address), - ).to.be.revertedWithCustomError(forwarder, 'ForwarderNotContractAddressError') - await expect( - new Forwarder__factory(owner).deploy(usdc.address, user.address, batcher.address, collateral.address), - ).to.be.revertedWithCustomError(forwarder, 'ForwarderNotContractAddressError') - await expect( - new Forwarder__factory(owner).deploy(user.address, dsu.address, user.address, collateral.address), - ).to.be.revertedWithCustomError(forwarder, 'ForwarderNotContractAddressError') - await expect( - new Forwarder__factory(owner).deploy(user.address, dsu.address, batcher.address, user.address), - ).to.be.revertedWithCustomError(forwarder, 'ForwarderNotContractAddressError') - }) - }) - - describe('#wrapAndDeposit', () => { - it('pulls USDC from the sender, wraps it as DSU and deposits it as collateral to the product account', async () => { - usdc.transferFrom.whenCalledWith(user.address, forwarder.address, 10e6).returns(true) - batcher.wrap.whenCalledWith(utils.parseEther('10'), forwarder.address).returns() - collateral.depositTo.whenCalledWith(account.address, product, utils.parseEther('10')).returns() - - await expect( - forwarder.connect(user).wrapAndDeposit( - account.address, - product.address, - utils.parseEther('10'), - { gasLimit: 30e6 }, // https://github.com/defi-wonderland/smock/issues/99 - ), - ) - .to.emit(forwarder, 'WrapAndDeposit') - .withArgs(account.address, product.address, utils.parseEther('10')) - - expect(usdc.transferFrom).to.have.been.calledOnceWith(user.address, forwarder.address, 10e6) - expect(batcher.wrap).to.have.been.calledOnceWith(utils.parseEther('10'), forwarder.address) - expect(collateral.depositTo).to.have.been.calledOnceWith(account.address, product.address, utils.parseEther('10')) - }) - - it('rounds correctly', async () => { - usdc.transferFrom.reset() - batcher.wrap.reset() - collateral.depositTo.reset() - - usdc.transferFrom.whenCalledWith(user.address, forwarder.address, 1e6).returns(true) - batcher.wrap.whenCalledWith(utils.parseEther('0.999999999999'), forwarder.address).returns() - collateral.depositTo.whenCalledWith(account.address, product, utils.parseEther('10')).returns() - - await expect( - forwarder.connect(user).wrapAndDeposit( - account.address, - product.address, - utils.parseEther('0.999999999999'), - { gasLimit: 30e6 }, // https://github.com/defi-wonderland/smock/issues/99 - ), - ) - .to.emit(forwarder, 'WrapAndDeposit') - .withArgs(account.address, product.address, utils.parseEther('0.999999999999')) - - expect(usdc.transferFrom).to.have.been.calledOnceWith(user.address, forwarder.address, 1e6) - expect(batcher.wrap).to.have.been.calledOnceWith(utils.parseEther('0.999999999999'), forwarder.address) - expect(collateral.depositTo).to.have.been.calledOnceWith( - account.address, - product.address, - utils.parseEther('0.999999999999'), - ) - }) - }) -}) diff --git a/packages/perennial/test/verification/mainnet/core/verifyCore.test.ts b/packages/perennial/test/verification/mainnet/core/verifyCore.test.ts index becb4f5d..5ae9d63f 100644 --- a/packages/perennial/test/verification/mainnet/core/verifyCore.test.ts +++ b/packages/perennial/test/verification/mainnet/core/verifyCore.test.ts @@ -7,8 +7,6 @@ import { Collateral__factory, Controller, Controller__factory, - Forwarder, - Forwarder__factory, Incentivizer, Incentivizer__factory, PerennialLens, @@ -32,7 +30,6 @@ describe('Core - Mainnet Verification', () => { let proxyAdmin: ProxyAdmin let upgradeableBeacon: UpgradeableBeacon let timelock: TimelockController - let forwarder: Forwarder let lens: PerennialLens beforeEach(async () => { @@ -44,7 +41,6 @@ describe('Core - Mainnet Verification', () => { proxyAdmin = ProxyAdmin__factory.connect(deployments['ProxyAdmin'].address, signer) upgradeableBeacon = UpgradeableBeacon__factory.connect(deployments['UpgradeableBeacon'].address, signer) timelock = TimelockController__factory.connect(deployments['TimelockController'].address, signer) - forwarder = Forwarder__factory.connect(deployments['Forwarder'].address, signer) lens = PerennialLens__factory.connect(deployments['PerennialLens_V01'].address, signer) }) @@ -188,12 +184,4 @@ describe('Core - Mainnet Verification', () => { expect(await lens.callStatic.controller()).to.equal(controller.address) }) }) - - /* describe('forwarder', () => { - it('has the correct configuration', async () => { - expect(await forwarder.DSU()).to.equal(deployments['DSU'].address) - expect(await forwarder.USDC()).to.equal(deployments['USDC'].address) - expect(await forwarder.batcher()).to.equal(deployments['Batcher'].address) - }) - }) */ }) From 4e2fa535e93abb9b1e3257b938d41b9b39364daf Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:04:01 -0400 Subject: [PATCH 02/25] Chainlink Bisection Oracle for Phase Discovery (#147) * Chainlink Bisection Oracle for Phase Discovery * more unit test coverage * fix integration test * add comments * improve comments, code readability * improve integration tests * minor cleanup * include uint64 cast * aggregatorRoundId helper --------- Co-authored-by: Kevin Britz --- .../contracts/ChainlinkFeedOracle.sol | 97 ++-- .../contracts/ChainlinkOracle.sol | 4 +- .../contracts/test/PassthroughDataFeed.sol | 33 ++ .../contracts/types/ChainlinkAggregator.sol | 104 ++++- .../contracts/types/ChainlinkRound.sol | 9 + .../ChainlinkFeedOracle.integrationTest.ts | 429 ++++++++++-------- .../ChainlinkFeedOracle.test.ts | 157 +++++-- 7 files changed, 561 insertions(+), 272 deletions(-) diff --git a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol index 34e0e402..73b6e869 100644 --- a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol @@ -6,14 +6,18 @@ import "./interfaces/IOracleProvider.sol"; import "./types/ChainlinkAggregator.sol"; /** - * @title ChainlinkOracle - * @notice Chainlink implementation of the IOracle interface. + * @title ChainlinkFeedOracle + * @notice Chainlink feed implementation of the IOracle interface. * @dev One instance per Chainlink price feed should be deployed. Multiple products may use the same * ChainlinkOracle instance if their payoff functions are based on the same underlying oracle. - * This implementation only support non-negative prices. + * This implementation only supports non-negative prices. */ contract ChainlinkFeedOracle is IOracleProvider { - error UnableToSyncError(); + + struct Phase { + uint128 startingVersion; + uint128 startingRoundId; + } /// @dev Chainlink feed aggregator address ChainlinkAggregator public immutable aggregator; @@ -21,16 +25,11 @@ contract ChainlinkFeedOracle is IOracleProvider { /// @dev Decimal offset used to normalize chainlink price to 18 decimals int256 private immutable _decimalOffset; - /// @dev Mapping of the starting data for each underlying phase - Phase[] private _phases; - /// @dev Last roundID seen when `sync` was called - uint256 private lastSyncedRoundId; + uint256 private _lastSyncedRoundId; - struct Phase { - uint128 startingVersion; - uint128 startingRoundId; - } + /// @dev Mapping of the starting data for each underlying phase + Phase[] private _phases; /** * @notice Initializes the contract state @@ -45,12 +44,12 @@ contract ChainlinkFeedOracle is IOracleProvider { // Load the phases array with empty phase values. these phases will be invalid if requested while (firstSeenRound.phaseId() > _phases.length) { - _phases.push(Phase(uint128(0), uint128(0))); + _phases.push(Phase(0, 0)); } // first seen round starts as version 0 at current phase - _phases.push(Phase(uint128(0), uint128(firstSeenRound.roundId))); - lastSyncedRoundId = firstSeenRound.roundId; + _phases.push(Phase(0, uint128(firstSeenRound.roundId))); + _lastSyncedRoundId = firstSeenRound.roundId; } /** @@ -67,30 +66,66 @@ contract ChainlinkFeedOracle is IOracleProvider { // Fetch latest round ChainlinkRound memory round = aggregator.getLatestRound(); - // Revert if the round id is 0 - if (uint64(round.roundId) == 0) revert InvalidOracleRound(); - - // If there is more than 1 phase to update, revert - if (round.phaseId() - _latestPhaseId() > 1) { - revert UnableToSyncError(); - } + // Revert if the aggregator round id is 0 which is an invalid round. + if (round.aggregatorRoundId() == 0) revert InvalidOracleRound(); // Update phase annotation when new phase detected - while (round.phaseId() > _latestPhaseId()) { - // Get the round count for the latest phase - (uint256 phaseRoundCount, uint256 nextStartingRoundId) = aggregator.getPhaseSwitchoverData( - _phases[_latestPhaseId()].startingRoundId, lastSyncedRoundId, round); - - // The starting version for the next phase is startingVersionForLatestPhase + roundCount + // `_lastSyncedRoundId` is the last round we have seen + // `round.roundId` is the current round + // + // When encountering a new phase, we need to find _lastSyncedRoundId + 1 (N + 1) + // `getPhaseSwitchoverData` will find the roundCount for the current phase, as well as the phaseId and roundId + // for the next non-empty phase. + // There are three cases: + // 1. N + 1 is in the same phase as `_lastSyncedRoundId` + // - `nextPhase` == round.phaseId(), and `nextStartingRoundId` == round.roundId + // 2. N + 1 is in some phase between _lastSyncedRoundId and the current phase + // - `nextPhase` < round.phaseId(), and starts at `nextStartingRoundId` + // 3. N + 1 is in the current phase + // - the `nextPhase` == round.phaseId(), and `nextStartingRoundId` < round.roundId + // + // Depending on the returned phase, we need to push empty phases into the phase array + // Empty phases are pushed between _lastSyncedRoundId.phase and (N + 1).phase + // and between (N + 1).phase and round.phase + if (round.phaseId() > _latestPhaseId()) { + // Get the round count for the lastSyncedRound phase, and the next phase information + (uint256 phaseRoundCount, uint16 nextPhase, uint256 nextStartingRoundId) = + aggregator.getPhaseSwitchoverData(_phases[_latestPhaseId()].startingRoundId, _lastSyncedRoundId, round); + + // If the next phase is not immediately after the latestPhase, push empty phases + // These phases will be invalid if queried + while (nextPhase > _latestPhaseId() + 1) { + _phases.push(Phase(_phases[_latestPhaseId()].startingVersion, 0)); + } + + // The starting version for the next phase is the phaseRoundCount plus startingVersion _phases.push( Phase( uint128(phaseRoundCount) + _phases[_latestPhaseId()].startingVersion, uint128(nextStartingRoundId) ) ); + + // If the intermediary phase is not `round`'s phase, fill in the intermediary phases + if (nextPhase < round.phaseId()) { + // After the intermediary phase is found, the phases up until round.phaseId can be skipped + while (round.phaseId() > _latestPhaseId() + 1) { + _phases.push(Phase(_phases[_latestPhaseId()].startingVersion, 0)); + } + + // And finally push the current phase + // We add 1 to the startingVersion for the previous phase because the intermediary phase is only + // 1 round long + _phases.push( + Phase( + 1 + _phases[_latestPhaseId()].startingVersion, + uint128(round.roundId) + ) + ); + } } - lastSyncedRoundId = round.roundId; + _lastSyncedRoundId = round.roundId; // Return packaged oracle version return _buildOracleVersion(round); @@ -155,7 +190,9 @@ contract ChainlinkFeedOracle is IOracleProvider { function _versionToPhase(uint256 version) private view returns (Phase memory phase) { uint256 phaseId = _latestPhaseId(); phase = _phases[phaseId]; - while (uint256(phase.startingVersion) > version) { + + // Exit if the phase is non-empty (startingRoundId != 0) and starts at a version less than or equal to `version` + while (phase.startingRoundId == 0 || uint256(phase.startingVersion) > version) { phaseId--; phase = _phases[phaseId]; } diff --git a/packages/perennial-oracle/contracts/ChainlinkOracle.sol b/packages/perennial-oracle/contracts/ChainlinkOracle.sol index 7dd31bfa..22234306 100644 --- a/packages/perennial-oracle/contracts/ChainlinkOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkOracle.sol @@ -8,10 +8,10 @@ import "./types/ChainlinkRegistry.sol"; /** * @title ChainlinkOracle - * @notice Chainlink implementation of the IOracle interface. + * @notice Chainlink registry implementation of the IOracle interface. * @dev One instance per Chainlink price feed should be deployed. Multiple products may use the same * ChainlinkOracle instance if their payoff functions are based on the same underlying oracle. - * This implementation only support non-negative prices. + * This implementation only supports non-negative prices. */ contract ChainlinkOracle is IOracleProvider { /// @dev Chainlink registry feed address diff --git a/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol b/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol index 06097b60..12f7e4a5 100644 --- a/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol +++ b/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol @@ -6,6 +6,16 @@ import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; contract PassthroughDataFeed { AggregatorV3Interface private _underlying; + struct LatestRoundData { + uint80 roundId; + int256 answer; + uint256 startedAt; + uint256 updatedAt; + uint80 answeredInRound; + } + + LatestRoundData private _roundOverride; + constructor(AggregatorV3Interface underlying_) { _underlying = underlying_; } @@ -19,6 +29,29 @@ contract PassthroughDataFeed { } function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) { + if (_roundOverride.roundId != 0) return ( + _roundOverride.roundId, + _roundOverride.answer, + _roundOverride.startedAt, + _roundOverride.updatedAt, + _roundOverride.answeredInRound + ); return _underlying.latestRoundData(); } + + function _setLatestRoundData( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) external { + _roundOverride = LatestRoundData( + roundId, + answer, + startedAt, + updatedAt, + answeredInRound + ); + } } diff --git a/packages/perennial-oracle/contracts/types/ChainlinkAggregator.sol b/packages/perennial-oracle/contracts/types/ChainlinkAggregator.sol index f7572416..742dafe5 100644 --- a/packages/perennial-oracle/contracts/types/ChainlinkAggregator.sol +++ b/packages/perennial-oracle/contracts/types/ChainlinkAggregator.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.13; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol"; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorProxyInterface.sol"; +import "@openzeppelin/contracts/utils/math/Math.sol"; import "./ChainlinkRound.sol"; /// @dev ChainlinkAggregator type @@ -54,6 +55,7 @@ library ChainlinkAggregatorLib { * @param lastSyncedRoundId last synced round ID for the proxy * @param latestRound latest round from the proxy * @return roundCount The number of rounds in the phase + * @return nextPhaseId The phaseID for the next phase * @return nextPhaseStartingRoundId The starting round ID for the next phase */ function getPhaseSwitchoverData( @@ -61,7 +63,7 @@ library ChainlinkAggregatorLib { uint256 startingRoundId, uint256 lastSyncedRoundId, ChainlinkRound memory latestRound - ) internal view returns (uint256 roundCount, uint256 nextPhaseStartingRoundId) { + ) internal view returns (uint256 roundCount, uint16 nextPhaseId, uint256 nextPhaseStartingRoundId) { AggregatorProxyInterface proxy = AggregatorProxyInterface(ChainlinkAggregator.unwrap(self)); // Try to get the immediate next round in the same phase. If this errors, we know that the phase has ended @@ -73,23 +75,103 @@ library ChainlinkAggregatorLib { if (nextRoundId == 0 || nextUpdatedAt == 0) { // Invalid round // pass } else if (nextUpdatedAt < latestRound.timestamp) { - return ((nextRoundId - startingRoundId) + 1, latestRound.roundId); + return ((nextRoundId - startingRoundId) + 1, latestRound.phaseId(), latestRound.roundId); } } catch { // pass } - // lastSyncedRound is the last round it's phase before latestRound, so we need to find where the next phase starts + // lastSyncedRound is the last round in it's phase before latestRound, so we need to find where the next phase starts // The next phase should start at the round that is closest to but after lastSyncedRound.timestamp - (,,,uint256 lastSyncedRoundTimestamp,) = proxy.getRoundData(uint80(lastSyncedRoundId)); - nextPhaseStartingRoundId = latestRound.roundId; - uint256 updatedAt = latestRound.timestamp; - // Walk back in the new phase until we dip below the lastSyncedRound.timestamp - while (updatedAt >= lastSyncedRoundTimestamp) { - nextPhaseStartingRoundId--; - (,,,updatedAt,) = proxy.getRoundData(uint80(nextPhaseStartingRoundId)); + ChainlinkRound memory lastSyncedRound = getRound(self, lastSyncedRoundId); + uint16 phaseToSearch = lastSyncedRound.phaseId(); + while (nextPhaseStartingRoundId == 0) { + phaseToSearch++; + nextPhaseStartingRoundId = getStartingRoundId(self, phaseToSearch, lastSyncedRound.timestamp); } - return ((lastSyncedRoundId - startingRoundId) + 1, nextPhaseStartingRoundId + 1); + return ((lastSyncedRoundId - startingRoundId) + 1, phaseToSearch, nextPhaseStartingRoundId); + } + + /** + * @notice Returns the round ID closest to but greater than targetTimestamp for the specified phase ID + * @param self Chainlink Feed Aggregator to operate on + * @param phaseId The specific phase to fetch data for + * @param targetTimestamp timestamp to search for + * @dev Assumes the phase ends at the aggregators latestRound or earlier + * @return The number of rounds in the phase + */ + function getStartingRoundId(ChainlinkAggregator self, uint16 phaseId, uint256 targetTimestamp) + internal view returns (uint256) { + AggregatorProxyInterface proxy = AggregatorProxyInterface(ChainlinkAggregator.unwrap(self)); + + (,,,uint256 startTimestamp,) = proxy.getRoundData(uint80(_aggregatorRoundIdToProxyRoundId(phaseId, 1))); + if (startTimestamp == 0) return 0; // Empty phase + + return _search(proxy, phaseId, targetTimestamp, startTimestamp, 1); + } + + /** + * Searches the given chainlink proxy for a round which has a timestamp which is as close to but greater than + * the `targetTimestamp` + * @param proxy Chainlink Proxy to search within + * @param phaseId Phase to search for round + * @param targetTimestamp Minimum timestamp value for found round + * @param minTimestamp Starting timestamp value + * @param minRoundId Starting round ID + */ + function _search(AggregatorProxyInterface proxy, uint16 phaseId, uint256 targetTimestamp, uint256 minTimestamp, uint256 minRoundId) private view returns (uint256) { + uint256 maxRoundId = minRoundId + 1000; // Start 1000 rounds away when searching for maximum + uint256 maxTimestamp = _tryGetProxyRoundData(proxy, phaseId, uint80(maxRoundId)); + + // Find the round bounds of the phase to perform the binary search + while (maxTimestamp <= targetTimestamp) { + minRoundId = maxRoundId; + minTimestamp = maxTimestamp; + maxRoundId = maxRoundId * 2; // Find bounds of phase by multiplying the max round by 2 + maxTimestamp = _tryGetProxyRoundData(proxy, phaseId, uint80(maxRoundId)); + } + + // Binary Search starts here. The algorithm calculates the middle round ID and finds it's timestamp + // If the midtimestamp is greater than target, set max to mid and continue + // If the midtimestamp is less than or equal to target, set min to mid and continue + // Exit when min + 1 is equal to or greater than max (no rounds between them) + while (minRoundId + 1 < maxRoundId) { + uint256 midRound = Math.average(minRoundId, maxRoundId); + uint256 midTimestamp = _tryGetProxyRoundData(proxy, phaseId, uint80(midRound)); + if (midTimestamp > targetTimestamp) { + maxTimestamp = midTimestamp; + maxRoundId = midRound; + } else { + minTimestamp = midTimestamp; + minRoundId = midRound; + } + } + + // If the found timestamp is not greater than target timestamp or no max was found, then the desired round does + // not exist in this phase + if (maxTimestamp <= targetTimestamp || maxTimestamp == type(uint256).max) return 0; + + return _aggregatorRoundIdToProxyRoundId(phaseId, uint80(maxRoundId)); + } + + function _tryGetProxyRoundData(AggregatorProxyInterface proxy, uint16 phaseId, uint80 tryRound) private view returns (uint256) { + try proxy.getRoundData(uint80(_aggregatorRoundIdToProxyRoundId(phaseId, tryRound))) returns (uint80,int256,uint256,uint256 timestamp,uint80) { + if (timestamp > 0) return timestamp; + } catch { + // pass + } + return type(uint256).max; + } + + /** + * @notice Convert an aggregator round ID into a proxy round ID for the given phase + * @dev Follows the logic specified in https://docs.chain.link/data-feeds/price-feeds/historical-data#roundid-in-proxy + * @param phaseId phase ID for the given aggregator round + * @param aggregatorRoundId round id for the aggregator round + * @return Proxy roundId + */ + function _aggregatorRoundIdToProxyRoundId(uint16 phaseId, uint80 aggregatorRoundId) private pure returns (uint256) { + return (uint256(phaseId) << 64) + aggregatorRoundId; } } diff --git a/packages/perennial-oracle/contracts/types/ChainlinkRound.sol b/packages/perennial-oracle/contracts/types/ChainlinkRound.sol index aed3b62a..afa078c5 100644 --- a/packages/perennial-oracle/contracts/types/ChainlinkRound.sol +++ b/packages/perennial-oracle/contracts/types/ChainlinkRound.sol @@ -27,4 +27,13 @@ library ChainlinkRoundLib { function phaseId(ChainlinkRound memory self) internal pure returns (uint16) { return uint16(self.roundId >> PHASE_OFFSET); } + + /** + * @notice Computes the chainlink aggregator round ID from a round + * @param self Round to compute from + * @return Chainlink aggregator round ID + */ + function aggregatorRoundId(ChainlinkRound memory self) internal pure returns (uint64) { + return uint64(self.roundId); + } } diff --git a/packages/perennial-oracle/test/integration/ChainlinkFeedOracle/ChainlinkFeedOracle.integrationTest.ts b/packages/perennial-oracle/test/integration/ChainlinkFeedOracle/ChainlinkFeedOracle.integrationTest.ts index b47397cd..454ae2f6 100644 --- a/packages/perennial-oracle/test/integration/ChainlinkFeedOracle/ChainlinkFeedOracle.integrationTest.ts +++ b/packages/perennial-oracle/test/integration/ChainlinkFeedOracle/ChainlinkFeedOracle.integrationTest.ts @@ -1,5 +1,4 @@ -import { smock, FakeContract } from '@defi-wonderland/smock' -import { BigNumber, utils } from 'ethers' +import { smock, MockContract } from '@defi-wonderland/smock' import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { expect } from 'chai' import HRE from 'hardhat' @@ -9,75 +8,49 @@ import { ChainlinkFeedOracle__factory, AggregatorProxyInterface, AggregatorProxyInterface__factory, + PassthroughDataFeed, + PassthroughDataFeed__factory, } from '../../../types/generated' import { reset } from '../../../../common/testutil/time' import { buildChainlinkRoundId } from '../../../util' const { ethers, config } = HRE -type ChainlinkRound = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] & { - roundId: BigNumber - answer: BigNumber - startedAt: BigNumber - updatedAt: BigNumber - answeredInRound: BigNumber -} -const PHASE_3_STARTING_ROUND = buildChainlinkRoundId(3, 1234) -const PHASE_4_STARTING_ROUND = buildChainlinkRoundId(4, 543) -const PHASE_5_STARTING_ROUND = buildChainlinkRoundId(5, 756) +const PHASE_3_LATEST_ROUND = buildChainlinkRoundId(3, 1234) +const PHASE_4_LATEST_ROUND = buildChainlinkRoundId(4, 543) +const PHASE_5_LATEST_ROUND = buildChainlinkRoundId(5, 28756) describe('ChainlinkFeedOracle', () => { let owner: SignerWithAddress let user: SignerWithAddress let aggregatorProxy: AggregatorProxyInterface - let aggregatorFake: FakeContract + let aggregatorMock: MockContract let oracle: ChainlinkFeedOracle - const phase3Data: ChainlinkRound[] = [] - const phase4Data: ChainlinkRound[] = [] - const phase5Data: ChainlinkRound[] = [] - beforeEach(async () => { await reset(config) ;[owner, user] = await ethers.getSigners() - aggregatorProxy = await AggregatorProxyInterface__factory.connect( - '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419', - owner, - ) - aggregatorFake = await smock.fake(AggregatorProxyInterface__factory.abi) - aggregatorFake.decimals.returns(await aggregatorProxy.decimals()) - - // Load 5 rounds of phase 3 - for (let i = 0; i < 5; i++) { - phase3Data.push(await aggregatorProxy.getRoundData(PHASE_3_STARTING_ROUND.add(i))) - aggregatorFake.getRoundData.whenCalledWith(PHASE_3_STARTING_ROUND.add(i)).returns(phase3Data[i]) - } - - // Load 5 rounds of phase 4 - for (let i = 0; i < 5; i++) { - phase4Data.push(await aggregatorProxy.getRoundData(PHASE_4_STARTING_ROUND.add(i))) - aggregatorFake.getRoundData.whenCalledWith(PHASE_4_STARTING_ROUND.add(i)).returns(phase4Data[i]) - } - - // Load 5 rounds of phase 5 - for (let i = 0; i < 5; i++) { - phase5Data.push(await aggregatorProxy.getRoundData(PHASE_5_STARTING_ROUND.add(i))) - aggregatorFake.getRoundData.whenCalledWith(PHASE_5_STARTING_ROUND.add(i)).returns(phase5Data[i]) - } - - aggregatorFake.latestRoundData.returns(phase3Data[0]) - oracle = await new ChainlinkFeedOracle__factory(owner).deploy(aggregatorFake.address) + const aggregatorMockFactory = await smock.mock('PassthroughDataFeed') + + aggregatorProxy = AggregatorProxyInterface__factory.connect('0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419', owner) + aggregatorMock = await aggregatorMockFactory.deploy(aggregatorProxy.address) + const latestData3 = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND) + // This is necessary because smock's mocking is buggy for some reason, likely due to naming collisions + await aggregatorMock._setLatestRoundData(...latestData3) + + oracle = await new ChainlinkFeedOracle__factory(owner).deploy(aggregatorMock.address) }) describe('#constructor', () => { it('sets initial params', async () => { - expect(await oracle.aggregator()).to.equal(aggregatorFake.address) + expect(await oracle.aggregator()).to.equal(aggregatorMock.address) }) it('returns version 0', async () => { + const expectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND) const atVersion = await oracle.atVersion(0) - expect(atVersion.price).to.equal(phase3Data[0].answer.mul(10 ** 10)) - expect(atVersion.timestamp).to.equal(phase3Data[0].updatedAt) + expect(atVersion.price).to.equal(expectedData.answer.mul(10 ** 10)) + expect(atVersion.timestamp).to.equal(expectedData.updatedAt) expect(atVersion.version).to.equal(0) }) }) @@ -87,260 +60,331 @@ describe('ChainlinkFeedOracle', () => { const returnValue = await oracle.callStatic.sync() oracle.connect(user).sync() - const expectedPrice = phase3Data[0].answer.mul(10 ** 10) + const expectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND) + const expectedPrice = expectedData.answer.mul(10 ** 10) expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase3Data[0].updatedAt) + expect(returnValue.timestamp).to.equal(expectedData.updatedAt) expect(returnValue.version).to.equal(0) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase3Data[0].updatedAt) + expect(currentVersion.timestamp).to.equal(expectedData.updatedAt) expect(currentVersion.version).to.equal(0) const atVersion = await oracle.atVersion(0) expect(atVersion.price).to.equal(expectedPrice) - expect(atVersion.timestamp).to.equal(phase3Data[0].updatedAt) + expect(atVersion.timestamp).to.equal(expectedData.updatedAt) expect(atVersion.version).to.equal(0) }) describe('after synced', async () => { beforeEach(async () => { - aggregatorFake.latestRoundData.returns(phase3Data[1]) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(1)))) await oracle.connect(user).sync() }) it('doesnt sync new version if not available', async () => { - const expectedPrice = phase3Data[1].answer.mul(10 ** 10) + const expectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(1)) + const expectedPrice = expectedData.answer.mul(10 ** 10) const returnValue = await oracle.callStatic.sync() oracle.connect(user).sync() expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase3Data[1].updatedAt) + expect(returnValue.timestamp).to.equal(expectedData.updatedAt) expect(returnValue.version).to.equal(1) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase3Data[1].updatedAt) + expect(currentVersion.timestamp).to.equal(expectedData.updatedAt) expect(currentVersion.version).to.equal(1) const atVersion = await oracle.atVersion(1) expect(atVersion.price).to.equal(expectedPrice) - expect(atVersion.timestamp).to.equal(phase3Data[1].updatedAt) + expect(atVersion.timestamp).to.equal(expectedData.updatedAt) expect(atVersion.version).to.equal(1) }) it('syncs new version if available', async () => { - const expectedPrice = phase3Data[2].answer.mul(10 ** 10) - aggregatorFake.latestRoundData.returns(phase3Data[2]) + const expectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(2)) + const expectedPrice = expectedData.answer.mul(10 ** 10) + await aggregatorMock._setLatestRoundData(...expectedData) const returnValue = await oracle.callStatic.sync() oracle.connect(user).sync() expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase3Data[2].updatedAt) + expect(returnValue.timestamp).to.equal(expectedData.updatedAt) expect(returnValue.version).to.equal(2) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase3Data[2].updatedAt) + expect(currentVersion.timestamp).to.equal(expectedData.updatedAt) expect(currentVersion.version).to.equal(2) const atVersion = await oracle.atVersion(2) expect(atVersion.price).to.equal(expectedPrice) - expect(atVersion.timestamp).to.equal(phase3Data[2].updatedAt) + expect(atVersion.timestamp).to.equal(expectedData.updatedAt) expect(atVersion.version).to.equal(2) }) it('syncs with new phase', async () => { // Sync up to version 3 which is in Phase 3 - aggregatorFake.latestRoundData.returns(phase3Data[3]) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(3)))) await oracle.connect(user).sync() // Next round comes from phase 4. // We check if there is another round in phase 3 (there is, which is version 4) so this corresponds to Version 5 - aggregatorFake.latestRoundData.returns(phase4Data[1]) + const expectedData = await aggregatorProxy.getRoundData(PHASE_4_LATEST_ROUND.add(1)) + await aggregatorMock._setLatestRoundData(...expectedData) - const expectedPrice = phase4Data[1].answer.mul(10 ** 10) + const expectedPrice = expectedData.answer.mul(10 ** 10) const returnValue = await oracle.callStatic.sync() await oracle.connect(user).sync() expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase4Data[1].updatedAt) + expect(returnValue.timestamp).to.equal(expectedData.updatedAt) expect(returnValue.version).to.equal(5) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase4Data[1].updatedAt) + expect(currentVersion.timestamp).to.equal(expectedData.updatedAt) expect(currentVersion.version).to.equal(5) const atVersion5 = await oracle.atVersion(5) expect(atVersion5.price).to.equal(expectedPrice) - expect(atVersion5.timestamp).to.equal(phase4Data[1].updatedAt) + expect(atVersion5.timestamp).to.equal(expectedData.updatedAt) expect(atVersion5.version).to.equal(5) + const version4ExpectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(4)) const atVersion4 = await oracle.atVersion(4) - expect(atVersion4.price).to.equal(phase3Data[4].answer.mul(10 ** 10)) - expect(atVersion4.timestamp).to.equal(phase3Data[4].updatedAt) + expect(atVersion4.price).to.equal(version4ExpectedData.answer.mul(10 ** 10)) + expect(atVersion4.timestamp).to.equal(version4ExpectedData.updatedAt) expect(atVersion4.version).to.equal(4) }) - it('syncs with new phase, next round in previous phase after latest round', async () => { + it('syncs with new phase 2 greater than current', async () => { // Sync up to version 3 which is in Phase 3 - aggregatorFake.latestRoundData.returns(phase3Data[3]) - aggregatorFake.getRoundData.whenCalledWith(phase3Data[4].roundId).returns([ - phase3Data[4].roundId, - phase3Data[4].answer, - phase4Data[1].startedAt, // Force this round to be after the newly synced one - phase4Data[1].updatedAt, - phase3Data[4].roundId, - ]) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(3)))) await oracle.connect(user).sync() - // Next round comes from phase 4. - // We check if there is another round in phase 3 - // There is, but it is after phase4Data[1] so we ignore it and perform a walkback - // The walkback goes back 1 round in the new phase, so this is version 5 - aggregatorFake.latestRoundData.returns(phase4Data[1]) + // Next round comes from phase 5. + // We check if there is another round in phase 3 (there is, which is version 4) so this corresponds to Version 5 + const expectedData = await aggregatorProxy.getRoundData(PHASE_5_LATEST_ROUND.add(1)) + await aggregatorMock._setLatestRoundData(...expectedData) - const expectedPrice = phase4Data[1].answer.mul(10 ** 10) + const expectedPrice = expectedData.answer.mul(10 ** 10) const returnValue = await oracle.callStatic.sync() await oracle.connect(user).sync() expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase4Data[1].updatedAt) + expect(returnValue.timestamp).to.equal(expectedData.updatedAt) expect(returnValue.version).to.equal(5) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase4Data[1].updatedAt) + expect(currentVersion.timestamp).to.equal(expectedData.updatedAt) expect(currentVersion.version).to.equal(5) const atVersion5 = await oracle.atVersion(5) expect(atVersion5.price).to.equal(expectedPrice) - expect(atVersion5.timestamp).to.equal(phase4Data[1].updatedAt) + expect(atVersion5.timestamp).to.equal(expectedData.updatedAt) expect(atVersion5.version).to.equal(5) + const version4ExpectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(4)) const atVersion4 = await oracle.atVersion(4) - expect(atVersion4.price).to.equal(phase4Data[0].answer.mul(10 ** 10)) - expect(atVersion4.timestamp).to.equal(phase4Data[0].updatedAt) + expect(atVersion4.price).to.equal(version4ExpectedData.answer.mul(10 ** 10)) + expect(atVersion4.timestamp).to.equal(version4ExpectedData.updatedAt) expect(atVersion4.version).to.equal(4) - - const atVersion3 = await oracle.atVersion(3) - expect(atVersion3.price).to.equal(phase3Data[3].answer.mul(10 ** 10)) - expect(atVersion3.timestamp).to.equal(phase3Data[3].updatedAt) - expect(atVersion3.version).to.equal(3) }) - it('syncs with new phase with walkback', async () => { - // Sync up to version 4 which is in Phase 3 - aggregatorFake.latestRoundData.returns(phase3Data[4]) - aggregatorFake.getRoundData.whenCalledWith(PHASE_3_STARTING_ROUND.add(5)).reverts() + it('syncs with new phase, next round in previous phase after latest round', async () => { + const p3r1237 = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(3)) + const p3r1238 = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(4)) + const p4r544 = await aggregatorProxy.getRoundData(PHASE_4_LATEST_ROUND.add(1)) + + // Sync up to version 3 which is in Phase 3 + await aggregatorMock._setLatestRoundData(...p3r1237) + aggregatorMock.getRoundData.whenCalledWith(PHASE_3_LATEST_ROUND.add(4)).returns([ + p3r1238.roundId, + p3r1238.answer, + p4r544.startedAt, // Force this round to be after the newly synced one + p4r544.updatedAt, + p3r1238.roundId, + ]) await oracle.connect(user).sync() // Next round comes from phase 4. - // We check if there is another round in phase 3 (there is not) - // so this corresponds to Version 6 and phase4Data[0] is version 5 - aggregatorFake.latestRoundData.returns(phase4Data[1]) + // We check if there is another round in phase 3 + // There is, but it is after phase4Data[1] so we ignore it and perform a search + // The search will phase 4 starts at round 2 (version 4), so this is version 4 + (544 - 2) = 546 + await aggregatorMock._setLatestRoundData(...p4r544) - const expectedPrice = phase4Data[1].answer.mul(10 ** 10) + const expectedPrice = p4r544.answer.mul(10 ** 10) const returnValue = await oracle.callStatic.sync() await oracle.connect(user).sync() expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase4Data[1].updatedAt) - expect(returnValue.version).to.equal(6) + expect(returnValue.timestamp).to.equal(p4r544.updatedAt) + expect(returnValue.version).to.equal(546) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase4Data[1].updatedAt) - expect(currentVersion.version).to.equal(6) - - const atVersion6 = await oracle.atVersion(6) - expect(atVersion6.price).to.equal(expectedPrice) - expect(atVersion6.timestamp).to.equal(phase4Data[1].updatedAt) - expect(atVersion6.version).to.equal(6) + expect(currentVersion.timestamp).to.equal(p4r544.updatedAt) + expect(currentVersion.version).to.equal(546) - const atVersion5 = await oracle.atVersion(5) - expect(atVersion5.price).to.equal(phase4Data[0].answer.mul(10 ** 10)) - expect(atVersion5.timestamp).to.equal(phase4Data[0].updatedAt) - expect(atVersion5.version).to.equal(5) + const atVersion5 = await oracle.atVersion(546) + expect(atVersion5.price).to.equal(expectedPrice) + expect(atVersion5.timestamp).to.equal(p4r544.updatedAt) + expect(atVersion5.version).to.equal(546) + const p4r2 = await aggregatorProxy.getRoundData(buildChainlinkRoundId(4, 2)) const atVersion4 = await oracle.atVersion(4) - expect(atVersion4.price).to.equal(phase3Data[4].answer.mul(10 ** 10)) - expect(atVersion4.timestamp).to.equal(phase3Data[4].updatedAt) + expect(atVersion4.price).to.equal(p4r2.answer.mul(10 ** 10)) + expect(atVersion4.timestamp).to.equal(p4r2.updatedAt) expect(atVersion4.version).to.equal(4) + + const atVersion3 = await oracle.atVersion(3) + expect(atVersion3.price).to.equal(p3r1237.answer.mul(10 ** 10)) + expect(atVersion3.timestamp).to.equal(p3r1237.updatedAt) + expect(atVersion3.version).to.equal(3) }) - it('syncs with new phase with multi-walkback', async () => { - // Sync up to version 4 which is in Phase 3 - aggregatorFake.latestRoundData.returns(phase3Data[4]) - aggregatorFake.getRoundData.whenCalledWith(PHASE_3_STARTING_ROUND.add(5)).reverts() + it('syncs with new phase with search', async () => { + const p3r1237 = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(3)) + const p4r544 = await aggregatorProxy.getRoundData(PHASE_4_LATEST_ROUND.add(1)) + aggregatorMock.getRoundData.whenCalledWith(PHASE_3_LATEST_ROUND.add(4)).reverts() + + // Sync up to version 3 which is in Phase 3 + await aggregatorMock._setLatestRoundData(...p3r1237) + await oracle.connect(user).sync() // Next round comes from phase 4. - // We check if there is another round in phase 3 (there is not) - - // Allow the walkback to stop at phase4Data[1] making phase4Data[2] the start of the phase - aggregatorFake.getRoundData - .whenCalledWith(PHASE_4_STARTING_ROUND.add(1)) - .returns([ - phase4Data[1].roundId, - phase4Data[1].answer, - phase3Data[4].startedAt.sub(5), - phase3Data[4].updatedAt.sub(5), - phase4Data[1].answeredInRound, - ]) - - // Due to the walkback, phase4 starts at phase4Data[2], so this is version 7 - aggregatorFake.latestRoundData.returns(phase4Data[4]) - - const expectedPrice = phase4Data[4].answer.mul(10 ** 10) + // We check if there is another round in phase 3 + // There is not + // The search will find phase 4 starts at round 2 (version 4), so this is version 4 + (544 - 2) = 546 + await aggregatorMock._setLatestRoundData(...p4r544) + + const expectedPrice = p4r544.answer.mul(10 ** 10) const returnValue = await oracle.callStatic.sync() await oracle.connect(user).sync() expect(returnValue.price).to.equal(expectedPrice) - expect(returnValue.timestamp).to.equal(phase4Data[4].updatedAt) - expect(returnValue.version).to.equal(7) + expect(returnValue.timestamp).to.equal(p4r544.updatedAt) + expect(returnValue.version).to.equal(546) const currentVersion = await oracle.currentVersion() expect(currentVersion.price).to.equal(expectedPrice) - expect(currentVersion.timestamp).to.equal(phase4Data[4].updatedAt) - expect(currentVersion.version).to.equal(7) - - const atVersion7 = await oracle.atVersion(7) - expect(atVersion7.price).to.equal(expectedPrice) - expect(atVersion7.timestamp).to.equal(phase4Data[4].updatedAt) - expect(atVersion7.version).to.equal(7) + expect(currentVersion.timestamp).to.equal(p4r544.updatedAt) + expect(currentVersion.version).to.equal(546) - const atVersion6 = await oracle.atVersion(6) - expect(atVersion6.price).to.equal(phase4Data[3].answer.mul(10 ** 10)) - expect(atVersion6.timestamp).to.equal(phase4Data[3].updatedAt) - expect(atVersion6.version).to.equal(6) - - const atVersion5 = await oracle.atVersion(5) - expect(atVersion5.price).to.equal(phase4Data[2].answer.mul(10 ** 10)) - expect(atVersion5.timestamp).to.equal(phase4Data[2].updatedAt) - expect(atVersion5.version).to.equal(5) + const atVersion5 = await oracle.atVersion(546) + expect(atVersion5.price).to.equal(expectedPrice) + expect(atVersion5.timestamp).to.equal(p4r544.updatedAt) + expect(atVersion5.version).to.equal(546) + const p4r2 = await aggregatorProxy.getRoundData(buildChainlinkRoundId(4, 2)) const atVersion4 = await oracle.atVersion(4) - expect(atVersion4.price).to.equal(phase3Data[4].answer.mul(10 ** 10)) - expect(atVersion4.timestamp).to.equal(phase3Data[4].updatedAt) + expect(atVersion4.price).to.equal(p4r2.answer.mul(10 ** 10)) + expect(atVersion4.timestamp).to.equal(p4r2.updatedAt) expect(atVersion4.version).to.equal(4) + + const atVersion3 = await oracle.atVersion(3) + expect(atVersion3.price).to.equal(p3r1237.answer.mul(10 ** 10)) + expect(atVersion3.timestamp).to.equal(p3r1237.updatedAt) + expect(atVersion3.version).to.equal(3) + }) + + it('syncs with new phase 2 phases away from the last with search', async () => { + // Sync up to the very last round in phase 3, version 25380 + const p3rLAST = await aggregatorProxy.getRoundData(buildChainlinkRoundId(3, 26614)) + await aggregatorMock._setLatestRoundData(...p3rLAST) + await oracle.connect(user).sync() + + // Next round comes from phase 5. + // The search will not find any phase 4 rounds that are after 3,26614 so then + // it will search phase 5, and find it starts at round 16247 (version 25381), so this is version 37890 + const p5r28756 = await aggregatorProxy.getRoundData(PHASE_5_LATEST_ROUND) + await aggregatorMock._setLatestRoundData(...p5r28756) + + const expectedPrice = p5r28756.answer.mul(10 ** 10) + const returnValue = await oracle.callStatic.sync() + await oracle.connect(user).sync() + + expect(returnValue.price).to.equal(expectedPrice) + expect(returnValue.timestamp).to.equal(p5r28756.updatedAt) + expect(returnValue.version).to.equal(37890) + + const currentVersion = await oracle.currentVersion() + expect(currentVersion.price).to.equal(expectedPrice) + expect(currentVersion.timestamp).to.equal(p5r28756.updatedAt) + expect(currentVersion.version).to.equal(37890) + + const atVersionCurrent = await oracle.atVersion(37890) + expect(atVersionCurrent.price).to.equal(expectedPrice) + expect(atVersionCurrent.timestamp).to.equal(p5r28756.updatedAt) + expect(atVersionCurrent.version).to.equal(37890) + + const expectedP5First = await aggregatorProxy.getRoundData(buildChainlinkRoundId(5, 16247)) + const atVersionIntermediary = await oracle.atVersion(25381) + expect(atVersionIntermediary.price).to.equal(expectedP5First.answer.mul(10 ** 10)) + expect(atVersionIntermediary.timestamp).to.equal(expectedP5First.updatedAt) + expect(atVersionIntermediary.version).to.equal(25381) + + const atVersionP3Last = await oracle.atVersion(25380) + expect(atVersionP3Last.price).to.equal(p3rLAST.answer.mul(10 ** 10)) + expect(atVersionP3Last.timestamp).to.equal(p3rLAST.updatedAt) + expect(atVersionP3Last.version).to.equal(25380) }) - it('reverts if syncing multiple phases in a single sync call', async () => { - aggregatorFake.latestRoundData.returns(phase5Data[0]) + it('syncs with new phase 2 phases away from the last with search and intermediary phase', async () => { + // Sync up to the very last round in phase 3, version 24766 + const p3rLAST = await aggregatorProxy.getRoundData(buildChainlinkRoundId(3, 26000)) + aggregatorMock.getRoundData.whenCalledWith(buildChainlinkRoundId(3, 26001)).reverts() + await aggregatorMock._setLatestRoundData(...p3rLAST) + await oracle.connect(user).sync() + + // The search will find that the next phase is 4 which starts at round 757 + // Phase 4 round 757 is version (26000 - 1234) + 1 = 24767 + // This is the first round in phase 5, version 24767 + const p5r28756 = await aggregatorProxy.getRoundData(PHASE_5_LATEST_ROUND) + await aggregatorMock._setLatestRoundData(...p5r28756) - await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'UnableToSyncError') + const expectedPrice = p5r28756.answer.mul(10 ** 10) + const returnValue = await oracle.callStatic.sync() + await oracle.connect(user).sync() + + expect(returnValue.price).to.equal(expectedPrice) + expect(returnValue.timestamp).to.equal(p5r28756.updatedAt) + expect(returnValue.version).to.equal(24768) + + const currentVersion = await oracle.currentVersion() + expect(currentVersion.price).to.equal(expectedPrice) + expect(currentVersion.timestamp).to.equal(p5r28756.updatedAt) + expect(currentVersion.version).to.equal(24768) + + const atVersionCurrent = await oracle.atVersion(24768) + expect(atVersionCurrent.price).to.equal(expectedPrice) + expect(atVersionCurrent.timestamp).to.equal(p5r28756.updatedAt) + expect(atVersionCurrent.version).to.equal(24768) + + const expectedP4 = await aggregatorProxy.getRoundData(buildChainlinkRoundId(4, 757)) + const atVersionIntermediary = await oracle.atVersion(24767) + expect(atVersionIntermediary.price).to.equal(expectedP4.answer.mul(10 ** 10)) + expect(atVersionIntermediary.timestamp).to.equal(expectedP4.updatedAt) + expect(atVersionIntermediary.version).to.equal(24767) + + const atVersionP3Last = await oracle.atVersion(24766) + expect(atVersionP3Last.price).to.equal(p3rLAST.answer.mul(10 ** 10)) + expect(atVersionP3Last.timestamp).to.equal(p3rLAST.updatedAt) + expect(atVersionP3Last.version).to.equal(24766) }) it('reverts on invalid round', async () => { const roundId = buildChainlinkRoundId(1, 0) - aggregatorFake.latestRoundData - .whenCalledWith() - .returns([roundId, phase3Data[0].answer, phase3Data[0].startedAt, phase3Data[0].updatedAt, roundId]) + aggregatorMock.latestRoundData.whenCalledWith().returns([roundId, 123, 123, 123, roundId]) await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'InvalidOracleRound') }) @@ -349,62 +393,65 @@ describe('ChainlinkFeedOracle', () => { describe('#atVersion', async () => { beforeEach(async () => { - aggregatorFake.latestRoundData.returns(phase3Data[3]) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(3)))) await oracle.connect(user).sync() }) it('reads prior version', async () => { + const expectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(1)) const atVersion = await oracle.atVersion(1) - expect(atVersion.price).to.equal(phase3Data[1].answer.mul(10 ** 10)) - expect(atVersion.timestamp).to.equal(phase3Data[1].updatedAt) + expect(atVersion.price).to.equal(expectedData.answer.mul(10 ** 10)) + expect(atVersion.timestamp).to.equal(expectedData.updatedAt) expect(atVersion.version).to.equal(1) }) it('reads versions in multiple phases', async () => { - // Phase 1 is Versions 0 -> 4 - // Phase 2 starts at Version 5 - aggregatorFake.latestRoundData.returns(phase4Data[1]) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(PHASE_4_LATEST_ROUND.add(1)))) // Syncs from Phase 3 to Phase 4 await oracle.connect(user).sync() // Syncs from beginning of Phase 4 to end (no more rounds in phase 4) - aggregatorFake.latestRoundData.returns(phase4Data[4]) + const phase4lastRound = buildChainlinkRoundId(4, 5056) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(phase4lastRound))) await oracle.connect(user).sync() - // Phase2 goes from versions 5 to 8 - // Start Phase 5, since we triggered a walkback - // phase5Data[0] is the starting round of the new phase - aggregatorFake.latestRoundData.returns(phase5Data[1]) + await aggregatorMock._setLatestRoundData(...(await aggregatorProxy.getRoundData(buildChainlinkRoundId(5, 2000)))) // Syncs from Phase 4 to Phase 5 + // Search will find the next round is phase 5, round 1434 await oracle.connect(user).sync() // Check Version from Phase 3: Versions 0 to 4 // Check last round of phase3 + const v4expectedData = await aggregatorProxy.getRoundData(PHASE_3_LATEST_ROUND.add(4)) const atVersionPhase3 = await oracle.atVersion(4) - expect(atVersionPhase3.price).to.equal(phase3Data[4].answer.mul(10 ** 10)) - expect(atVersionPhase3.timestamp).to.equal(phase3Data[4].updatedAt) + expect(atVersionPhase3.price).to.equal(v4expectedData.answer.mul(10 ** 10)) + expect(atVersionPhase3.timestamp).to.equal(v4expectedData.updatedAt) expect(atVersionPhase3.version).to.equal(4) - // Check Version from Phase 4: Versions 5 to 8 + // Check Version from Phase 4: Versions 5 to end // Check first round of phase4 + const v5expectedData = await aggregatorProxy.getRoundData(PHASE_4_LATEST_ROUND.add(1)) const atVersionPhase4 = await oracle.atVersion(5) - expect(atVersionPhase4.price).to.equal(phase4Data[1].answer.mul(10 ** 10)) - expect(atVersionPhase4.timestamp).to.equal(phase4Data[1].updatedAt) + expect(atVersionPhase4.price).to.equal(v5expectedData.answer.mul(10 ** 10)) + expect(atVersionPhase4.timestamp).to.equal(v5expectedData.updatedAt) expect(atVersionPhase4.version).to.equal(5) // Check last round of phase4 - const atVersionPhase4Last = await oracle.atVersion(8) - expect(atVersionPhase4Last.price).to.equal(phase4Data[4].answer.mul(10 ** 10)) - expect(atVersionPhase4Last.timestamp).to.equal(phase4Data[4].updatedAt) - expect(atVersionPhase4Last.version).to.equal(8) - - // Check Version from Phase 5: Versions 9 onwards - // Check first round of phase 5 - const atVersionPhase5 = await oracle.atVersion(9) - expect(atVersionPhase5.price).to.equal(phase5Data[0].answer.mul(10 ** 10)) - expect(atVersionPhase5.timestamp).to.equal(phase5Data[0].updatedAt) - expect(atVersionPhase5.version).to.equal(9) + // Phase 4 is (5056-544)=4512 rounds long and starts at version 5, so this is version 5+4512=4517 + const phase4LastExpectedData = await aggregatorProxy.getRoundData(phase4lastRound) + const atVersionPhase4Last = await oracle.atVersion(4517) + expect(atVersionPhase4Last.price).to.equal(phase4LastExpectedData.answer.mul(10 ** 10)) + expect(atVersionPhase4Last.timestamp).to.equal(phase4LastExpectedData.updatedAt) + expect(atVersionPhase4Last.version).to.equal(4517) + + // Check Version from Phase 5: Versions 4518 onwards + // Check first round of phase 5, which is round 1434 found by the binary search + const v9expectedData = await aggregatorProxy.getRoundData(buildChainlinkRoundId(5, 1434)) + const atVersionPhase5 = await oracle.atVersion(4518) + expect(atVersionPhase5.price).to.equal(v9expectedData.answer.mul(10 ** 10)) + expect(atVersionPhase5.timestamp).to.equal(v9expectedData.updatedAt) + expect(atVersionPhase5.version).to.equal(4518) }) }) }) diff --git a/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts b/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts index deb43a29..702820b2 100644 --- a/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts +++ b/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts @@ -1,5 +1,5 @@ import { smock, FakeContract } from '@defi-wonderland/smock' -import { utils } from 'ethers' +import { BigNumber, BigNumberish, utils } from 'ethers' import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { expect } from 'chai' import HRE from 'hardhat' @@ -201,49 +201,53 @@ describe('ChainlinkFeedOracle', () => { expect(atVersion.version).to.equal(26) }) - it('syncs with new phase with walkback', async () => { + it('syncs with new phase with search', async () => { + // No next round in the current phase const phase1NextRound = buildChainlinkRoundId(INITIAL_PHASE, INITIAL_ROUND + 25) aggregatorProxy.getRoundData.whenCalledWith(phase1NextRound).reverts() // This is the first seen round of the new phase // Phase 1 was (36 - 12 + 1) = 25 rounds long (versions 0 to 24) - // Phase 2 starts at version 25 which is 2 rounds before this due to walkback, so this is version 27 - const roundId = buildChainlinkRoundId(INITIAL_PHASE + 1, 345) + // Phase 2 starts at version 25, which is 2 rounds before 1345 + const phase2SwitchoverRound = buildChainlinkRoundId(INITIAL_PHASE + 1, 1343) + const roundId = buildChainlinkRoundId(INITIAL_PHASE + 1, 1345) + + // Setup the binary search logic. If the searched for round is below switchoverRound, then return TIMESTAMP_START + // If the round is after switchoverRound, return invalid round + // If the round is switchoverRound, return slightly greater than TIMESTAMP_START + aggregatorProxy.getRoundData.returns((args: BigNumberish[]) => { + const roundRequested = BigNumber.from(args[0]) + if (roundRequested.eq(roundId)) { + return [ + roundId, + ethers.BigNumber.from(133300000000), + TIMESTAMP_START + HOUR, + TIMESTAMP_START + HOUR, + roundId, + ] + } else if (roundRequested.gt(phase2SwitchoverRound)) { + return [roundRequested, 0, 0, 0, roundRequested] + } else if (roundRequested.lt(phase2SwitchoverRound)) { + return [roundRequested, 0, TIMESTAMP_START, TIMESTAMP_START, roundRequested] + } + + return [ + phase2SwitchoverRound, + ethers.BigNumber.from(133200000000), + TIMESTAMP_START + 1, + TIMESTAMP_START + 1, + phase2SwitchoverRound, + ] + }) + aggregatorProxy.latestRoundData .whenCalledWith() - .returns([roundId, ethers.BigNumber.from(133300000000), TIMESTAMP_START, TIMESTAMP_START + HOUR, roundId]) - - aggregatorProxy.getRoundData - .whenCalledWith(roundId) - .returns([roundId, ethers.BigNumber.from(133300000000), TIMESTAMP_START, TIMESTAMP_START + HOUR, roundId]) - - // Walk back in phase until crossover point - aggregatorProxy.getRoundData - .whenCalledWith(roundId.sub(1)) - .returns([ - roundId.sub(1), - ethers.BigNumber.from(122200000000), - TIMESTAMP_START + HOUR, - TIMESTAMP_START + HOUR, - roundId.sub(1), - ]) - aggregatorProxy.getRoundData - .whenCalledWith(roundId.sub(2)) .returns([ - roundId.sub(1), - ethers.BigNumber.from(122200000000), + roundId, + ethers.BigNumber.from(133300000000), TIMESTAMP_START + HOUR, TIMESTAMP_START + HOUR, - roundId.sub(1), - ]) - aggregatorProxy.getRoundData - .whenCalledWith(roundId.sub(3)) - .returns([ - roundId.sub(1), - ethers.BigNumber.from(122200000000), - TIMESTAMP_START - HOUR, - TIMESTAMP_START - HOUR, - roundId.sub(2), + roundId, ]) const returnValue = await oracle.callStatic.sync() @@ -262,15 +266,92 @@ describe('ChainlinkFeedOracle', () => { expect(atVersion.price).to.equal(utils.parseEther('1333')) expect(atVersion.timestamp).to.equal(TIMESTAMP_START + HOUR) expect(atVersion.version).to.equal(27) + + const atVersion25 = await oracle.atVersion(25) + expect(atVersion25.price).to.equal(utils.parseEther('1332')) + expect(atVersion25.timestamp).to.equal(TIMESTAMP_START + 1) + expect(atVersion25.version).to.equal(25) }) - it('reverts if syncing multiple phases in a single sync call', async () => { - const roundId = buildChainlinkRoundId(INITIAL_PHASE + 2, 345) + it('syncs with new phase that is 5 greater current phase with search', async () => { + const phase1NextRound = buildChainlinkRoundId(INITIAL_PHASE, INITIAL_ROUND + 25) + aggregatorProxy.getRoundData + .whenCalledWith(phase1NextRound) + .returns([phase1NextRound, 0, 0, 0, phase1NextRound]) + + // This is the first seen round of Phase 6 + // Phase 1 was (36 - 12 + 1) = 25 rounds long (versions 0 to 24) + // Phase 4 contains version 25 + // Phase 6 starts at version 26 + const roundId = buildChainlinkRoundId(INITIAL_PHASE + 5, 345) + const phase4SwitchoverRound = buildChainlinkRoundId(INITIAL_PHASE + 3, 112) + + // Setup the binary search logic for phase 4 + // If the round is equal to 6,345, return TIMESTAMP_START + HOUR + // If the round is below 4,112, return TIMESTAMP_START - 1 + // If the round is after 4,112, return TIMESTAMP_START + 2 * HOUR + // If the round is equal to 4,112, return TIMESTAMP_START + 1 + aggregatorProxy.getRoundData.returns((args: BigNumberish[]) => { + const roundRequested = BigNumber.from(args[0]) + const phaseRequested = Number(roundRequested.toBigInt() >> BigInt(64)) + + if (roundRequested.eq(roundId)) { + return [ + roundId, + ethers.BigNumber.from(133300000000), + TIMESTAMP_START + HOUR, + TIMESTAMP_START + HOUR, + roundId, + ] + } else if (roundRequested.gt(phase4SwitchoverRound)) { + return [roundRequested, 0, TIMESTAMP_START + 2 * HOUR, TIMESTAMP_START + 2 * HOUR, roundRequested] + } else if (roundRequested.lt(phase4SwitchoverRound)) { + if (phaseRequested < 4 && roundRequested.gt(buildChainlinkRoundId(phaseRequested, 1000))) { + // Only go 1000 rounds into phase 2 and 3 + return [roundRequested, 0, 0, 0, roundRequested] + } + return [roundRequested, 0, TIMESTAMP_START, TIMESTAMP_START, roundRequested] + } + return [ + phase4SwitchoverRound, + ethers.BigNumber.from(133200000000), + TIMESTAMP_START + 1, + TIMESTAMP_START + 1, + phase4SwitchoverRound, + ] + }) + aggregatorProxy.latestRoundData .whenCalledWith() - .returns([roundId, ethers.BigNumber.from(133300000000), TIMESTAMP_START, TIMESTAMP_START + HOUR, roundId]) + .returns([ + roundId, + ethers.BigNumber.from(133300000000), + TIMESTAMP_START + HOUR, + TIMESTAMP_START + HOUR, + roundId, + ]) + + const returnValue = await oracle.callStatic.sync() + await oracle.connect(user).sync() + + expect(returnValue.price).to.equal(utils.parseEther('1333')) + expect(returnValue.timestamp).to.equal(TIMESTAMP_START + HOUR) + expect(returnValue.version).to.equal(26) + + const currentVersion = await oracle.currentVersion() + expect(currentVersion.price).to.equal(utils.parseEther('1333')) + expect(currentVersion.timestamp).to.equal(TIMESTAMP_START + HOUR) + expect(currentVersion.version).to.equal(26) + + const atVersion = await oracle.atVersion(26) + expect(atVersion.price).to.equal(utils.parseEther('1333')) + expect(atVersion.timestamp).to.equal(TIMESTAMP_START + HOUR) + expect(atVersion.version).to.equal(26) - await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'UnableToSyncError') + const atVersion25 = await oracle.atVersion(25) + expect(atVersion25.price).to.equal(utils.parseEther('1332')) + expect(atVersion25.timestamp).to.equal(TIMESTAMP_START + 1) + expect(atVersion25.version).to.equal(25) }) it('reverts on invalid round', async () => { From c6b05923e8a1595c027a6764ca68e8169da7276e Mon Sep 17 00:00:00 2001 From: test9955667 <79500129+test9955667@users.noreply.github.com> Date: Sun, 16 Apr 2023 20:36:22 -0500 Subject: [PATCH 03/25] MultiInvokerRollup (#141) * Create README.md * Update README.md * Update README.md * started concept for multiinvoker rollup optimization * Update README.md * Update README.md * changed visibility of invoker actions * adding testing for rollup invoker * finished unit tests of multiinvokerrollup * cleanup solidity + implement pr suggestions * update interface * deployment * wrap / unwrap prefixing fix * delete file * more style and comments * decode uint len < 32 check + more cleanup * more style * comment coverage * function visibility, mutability, ordering * comment formatting + coverage * more comment cleanup * more nitpicks * brizzle logical changes * move uint length check to relevant * move uint length check to relevant * simplify function levels * simplify function levels * style changes * update cache storage scheme * deploy new proxy and impl * add isRollup util * handle both rollup and non rollup deployments * update rollup invoker * final sc cleanup * update deploy * update test * integration tests * more coverage * coverage + fixed tests * added error coverage and moved revert up level * fix internal calls, update tests * remove .only --------- Co-authored-by: Kevin Britz Co-authored-by: Arjun Rao <2940142+arjun-io@users.noreply.github.com> --- packages/common/testutil/network.ts | 5 + .../interfaces/IMultiInvokerRollup.sol | 18 + .../contracts/multiinvoker/MultiInvoker.sol | 133 +- .../multiinvoker/MultiInvokerRollup.sol | 289 + .../deploy/004_deploy_multiinvoker.ts | 24 +- .../arbitrumGoerli/MultiInvoker_Impl.json | 206 +- .../arbitrumGoerli/MultiInvoker_Proxy.json | 44 +- .../181d5952a5d0fca85831e55cf8991318.json | 420 ++ .../d0dcdcd7c0b6f58f746ab3d6e5ce337c.json | 423 ++ .../test/integration/helpers/setupHelpers.ts | 18 + ...tiinvoker.test.ts => multiInvoker.test.ts} | 18 +- .../multiinvoker/multiInvokerRollup.test.ts | 567 ++ .../multiinvoker/MultiInvokerRollup.test.ts | 631 +++ packages/perennial/test/util.ts | 181 +- yarn.lock | 4729 ++++++++--------- 15 files changed, 5117 insertions(+), 2589 deletions(-) create mode 100644 packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol create mode 100644 packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol create mode 100644 packages/perennial/deployments/arbitrumGoerli/solcInputs/181d5952a5d0fca85831e55cf8991318.json create mode 100644 packages/perennial/deployments/arbitrumGoerli/solcInputs/d0dcdcd7c0b6f58f746ab3d6e5ce337c.json rename packages/perennial/test/integration/multiinvoker/{multiinvoker.test.ts => multiInvoker.test.ts} (97%) create mode 100644 packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts create mode 100644 packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts diff --git a/packages/common/testutil/network.ts b/packages/common/testutil/network.ts index 8fc7cd40..850ccb0b 100644 --- a/packages/common/testutil/network.ts +++ b/packages/common/testutil/network.ts @@ -119,3 +119,8 @@ export function isLocalhost(networkName: string): boolean { return false } } + +export function isRollup(networkName: string): boolean { + if (isBase(networkName) || isArbitrum(networkName) || isOptimism(networkName)) return true + return false +} diff --git a/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol b/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol new file mode 100644 index 00000000..0ce564c7 --- /dev/null +++ b/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.13; + +import "./IMultiInvoker.sol"; + +interface IMultiInvokerRollup is IMultiInvoker { + struct PTR { + uint256 pos; + } + + event AddressAddedToCache(address indexed value, uint256 index); + + error MultiInvokerRollupAddressIndexOutOfBoundsError(); + error MultiInvokerRollupInvalidUint256LengthError(); + + function addressCache(uint256 index) external view returns(address); + function addressLookup(address value) external view returns(uint256 index); +} diff --git a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol index 45544c82..494641f0 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol @@ -68,99 +68,136 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param invocations The list of invocations to execute in order */ function invoke(Invocation[] calldata invocations) external { + for (uint256 i = 0; i < invocations.length; i++) { Invocation memory invocation = invocations[i]; // Deposit from `msg.sender` into `account`s `product` collateral account if (invocation.action == PerennialAction.DEPOSIT) { (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18)); - depositTo(account, product, amount); + _deposit(account, product, amount); // Withdraw from `msg.sender`s `product` collateral account to `receiver` } else if (invocation.action == PerennialAction.WITHDRAW) { (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18)); - collateral.withdrawFrom(msg.sender, receiver, product, amount); + _withdraw(receiver, product, amount); // Open a take position on behalf of `msg.sender` } else if (invocation.action == PerennialAction.OPEN_TAKE) { (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18)); - product.openTakeFor(msg.sender, amount); + _openTake(product, amount); // Close a take position on behalf of `msg.sender` } else if (invocation.action == PerennialAction.CLOSE_TAKE) { (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18)); - product.closeTakeFor(msg.sender, amount); + _closeTake(product, amount); // Open a make position on behalf of `msg.sender` } else if (invocation.action == PerennialAction.OPEN_MAKE) { (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18)); - product.openMakeFor(msg.sender, amount); + _openMake(product, amount); // Close a make position on behalf of `msg.sender` } else if (invocation.action == PerennialAction.CLOSE_MAKE) { (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18)); - product.closeMakeFor(msg.sender, amount); + _closeMake(product, amount); // Claim `msg.sender`s incentive reward for `product` programs } else if (invocation.action == PerennialAction.CLAIM) { (IProduct product, uint256[] memory programIds) = abi.decode(invocation.args, (IProduct, uint256[])); - controller.incentivizer().claimFor(msg.sender, product, programIds); + _claim(product, programIds); // Wrap `msg.sender`s USDC into DSU and return the DSU to `account` } else if (invocation.action == PerennialAction.WRAP) { (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18)); - wrap(receiver, amount); + _wrap(receiver, amount); // Unwrap `msg.sender`s DSU into USDC and return the USDC to `account` } else if (invocation.action == PerennialAction.UNWRAP) { (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18)); - unwrap(receiver, amount); + _unwrap(receiver, amount); // Wrap `msg.sender`s USDC into DSU and deposit into `account`s `product` collateral account } else if (invocation.action == PerennialAction.WRAP_AND_DEPOSIT) { (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18)); - wrapAndDeposit(account, product, amount); + _wrapAndDeposit(account, product, amount); } // Withdraw DSU from `msg.sender`s `product` collateral account, unwrap into USDC, and return the USDC to `receiver` else if (invocation.action == PerennialAction.WITHDRAW_AND_UNWRAP) { (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18)); - withdrawAndUnwrap(receiver, product, amount); + _withdrawAndUnwrap(receiver, product, amount); } // Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account` else if (invocation.action == PerennialAction.VAULT_DEPOSIT) { (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18)); - vaultDeposit(account, vault, amount); + _vaultDeposit(account, vault, amount); } // Redeem `shares` from from `vault` on behalf of `msg.sender` else if (invocation.action == PerennialAction.VAULT_REDEEM) { (IPerennialVault vault, UFixed18 shares) = abi.decode(invocation.args, (IPerennialVault, UFixed18)); - vault.redeem(shares, msg.sender); + _vaultRedeem(vault, shares); } // Claim assets from `vault` on behalf of `owner` else if (invocation.action == PerennialAction.VAULT_CLAIM) { (address owner, IPerennialVault vault) = abi.decode(invocation.args, (address, IPerennialVault)); - vault.claim(owner); + _vaultClaim(vault, owner); } // Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault` else if (invocation.action == PerennialAction.VAULT_WRAP_AND_DEPOSIT) { (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18)); - vaultWrapAndDeposit(account, vault, amount); + _vaultWrapAndDeposit(account, vault, amount); } } } + /** + * @notice opens `amount` of take on behalf of `msg.sender` in `product` + * @param product Product to increase take position of + * @param amount Amount to increase take position by + */ + function _openTake(IProduct product, UFixed18 amount) internal { + product.openTakeFor(msg.sender, amount); + } + + /** + * @notice closes `amount` of take on behalf of `msg.sender` in `product` + * @param product Product to decrease take position of + * @param amount Amount to decrease take position by + */ + function _closeTake(IProduct product, UFixed18 amount) internal { + product.closeTakeFor(msg.sender, amount); + } + + /** + * @notice opens `amount` of make on behalf of `msg.sender` in `product` + * @param product Product to increase make position of + * @param amount Amount to increase make position by + */ + function _openMake(IProduct product, UFixed18 amount) internal { + product.openMakeFor(msg.sender, amount); + } + + /** + * @notice closes `amount` of make on behalf of `msg.sender` in `product` + * @param product Product to decrease make position of + * @param amount Amount to decrease make position by + */ + function _closeMake(IProduct product, UFixed18 amount) internal { + product.closeMakeFor(msg.sender, amount); + } + /** * @notice Deposits `amount` DSU from `msg.sender` into `account`s `product` collateral account * @param account Account to deposit funds on behalf of * @param product Product to deposit funds for * @param amount Amount of DSU to deposit into the collateral account */ - function depositTo(address account, IProduct product, UFixed18 amount) private { + function _deposit(address account, IProduct product, UFixed18 amount) internal { // Pull the token from the `msg.sender` DSU.pull(msg.sender, amount); @@ -168,16 +205,34 @@ contract MultiInvoker is IMultiInvoker, UInitializable { collateral.depositTo(account, product, amount); } + /** + * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account to `receiver` + * @param receiver address to withdraw funds on behalf of msg.sender to + * @param product Product to withdraw frunds from + * @param amount Amount of DSU to withdraw out of the collateral account + */ + function _withdraw(address receiver, IProduct product, UFixed18 amount) internal { + collateral.withdrawFrom(msg.sender, receiver, IProduct(product), amount); + } + + /** + * @notice Claim `msg.sender`s incentive reward for `product` programs + * @param product Product to claim + */ + function _claim(IProduct product, uint256[] memory programIds) internal { + controller.incentivizer().claimFor(msg.sender, product, programIds); + } + /** * @notice Wraps `amount` USDC into DSU, pulling from `msg.sender` and sending to `receiver` * @param receiver Address to receive the DSU * @param amount Amount of USDC to wrap */ - function wrap(address receiver, UFixed18 amount) private { + function _wrap(address receiver, UFixed18 amount) internal { // Pull USDC from the `msg.sender` USDC.pull(msg.sender, amount, true); - _wrap(receiver, amount); + _handleWrap(receiver, amount); } /** @@ -185,11 +240,11 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param receiver Address to receive the USDC * @param amount Amount of DSU to unwrap */ - function unwrap(address receiver, UFixed18 amount) private { + function _unwrap(address receiver, UFixed18 amount) internal { // Pull the token from the `msg.sender` DSU.pull(msg.sender, amount); - _unwrap(receiver, amount); + _handleUnwrap(receiver, amount); } /** @@ -198,11 +253,11 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param product Product to deposit funds for * @param amount Amount of USDC to deposit into the collateral account */ - function wrapAndDeposit(address account, IProduct product, UFixed18 amount) private { + function _wrapAndDeposit(address account, IProduct product, UFixed18 amount) internal { // Pull USDC from the `msg.sender` USDC.pull(msg.sender, amount, true); - _wrap(address(this), amount); + _handleWrap(address(this), amount); // Deposit the amount to the collateral account collateral.depositTo(account, product, amount); @@ -214,11 +269,11 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param product Product to withdraw funds for * @param amount Amount of DSU to withdraw from the collateral account */ - function withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) private { + function _withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) internal { // Withdraw the amount from the collateral account collateral.withdrawFrom(msg.sender, address(this), product, amount); - _unwrap(receiver, amount); + _handleUnwrap(receiver, amount); } /** @@ -227,7 +282,7 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param vault Vault to deposit funds into * @param amount Amount of DSU to deposit into the vault */ - function vaultDeposit(address account, IPerennialVault vault, UFixed18 amount) private { + function _vaultDeposit(address account, IPerennialVault vault, UFixed18 amount) internal { // Pull the DSU from the user DSU.pull(msg.sender, amount); @@ -238,17 +293,37 @@ contract MultiInvoker is IMultiInvoker, UInitializable { vault.deposit(amount, account); } + /** + * @notice Redeems `shares` shares from the vault on behalf of `msg.sender` + * @dev Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets + * If account is not msg.sender, requires prior spending approval + * @param shares Amount of shares to redeem + * @param vault Vault to redeem from + */ + function _vaultRedeem(IPerennialVault vault, UFixed18 shares) internal { + vault.redeem(shares, msg.sender); + } + + /** + * @notice Claims all claimable assets for account, sending assets to account + * @param vault Vault to claim from + * @param owner Account to claim for + */ + function _vaultClaim(IPerennialVault vault, address owner) internal { + vault.claim(owner); + } + /** * @notice Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault` * @param account Address to receive the vault shares * @param vault Vault to deposit funds into * @param amount Amount of USDC to wrap and deposit into the vault */ - function vaultWrapAndDeposit(address account, IPerennialVault vault, UFixed18 amount) private { + function _vaultWrapAndDeposit(address account, IPerennialVault vault, UFixed18 amount) internal { // Pull USDC from the `msg.sender` USDC.pull(msg.sender, amount, true); - _wrap(address(this), amount); + _handleWrap(address(this), amount); // Just-in-time approval to the vault for the amount being deposited DSU.approve(address(vault), amount); @@ -262,7 +337,7 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param receiver Address to receive the DSU * @param amount Amount of USDC to wrap */ - function _wrap(address receiver, UFixed18 amount) private { + function _handleWrap(address receiver, UFixed18 amount) internal { // If the batcher is 0 or doesn't have enough for this wrap, go directly to the reserve if (address(batcher) == address(0) || amount.gt(DSU.balanceOf(address(batcher)))) { reserve.mint(amount); @@ -278,7 +353,7 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param receiver Address to receive the USDC * @param amount Amount of DSU to unwrap */ - function _unwrap(address receiver, UFixed18 amount) private { + function _handleUnwrap(address receiver, UFixed18 amount) internal { // If the batcher is 0 or doesn't have enough for this unwrap, go directly to the reserve if (address(batcher) == address(0) || amount.gt(USDC.balanceOf(address(batcher)))) { reserve.redeem(amount); diff --git a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol new file mode 100644 index 00000000..e948d353 --- /dev/null +++ b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.15; + +import "./MultiInvoker.sol"; +import "../interfaces/IMultiInvokerRollup.sol"; + +/** + * @title MultiInvokerRollup + * @notice A calldata-optimized implementation of the Perennial MultiInvoker + * @dev Supports the following encoding algorithm: + + 1) List of Actions + * At the top-level input, the MultiInvoker takes a list of actions + * Each action is encoded using the below specification then concatenated together + + 2) Actions + * First byte is the uint8 of the action's enum + * Rest of the data is a list of params encoded using the below specification then concatenated together + + 3) Parameters + * uint256 - first byte is length, data is packed into smallest byte length that will fit value + * uint256[] - first byte is array length, each element is packed as a uint256 and concatenated together + * Address + 1) If address is already cached, index of the address is encoded as a uint256 + 2) Otherwise the first byte is encoded as 0, and the following 20 bytes are the address + */ +contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { + + /// @dev Number of bytes in a uint256 type + uint256 private constant UINT256_LENGTH = 32; + + /// @dev Number of bytes in a address type + uint256 private constant ADDRESS_LENGTH = 20; + + /// @dev Number of bytes in a uint8 type + uint256 private constant UINT8_LENGTH = 1; + + /// @dev Array of all stored addresses (users, products, vaults, etc) for calldata packing + address[] public addressCache; + + /// @dev Index lookup of above array for constructing calldata + mapping(address => uint256) public addressLookup; + + /** + * @notice Constructs the contract + * @param usdc_ The USDC token contract address + * @param reserve_ The DSU batcher contract address + * @param reserve_ The DSU reserve contract address + * @param controller_ The Perennial controller contract address + */ + constructor(Token6 usdc_, IBatcher batcher_, IEmptySetReserve reserve_, IController controller_) + MultiInvoker(usdc_, batcher_, reserve_, controller_) + { + _cacheAddress(address(0)); // Cache 0-address to avoid 0-index lookup collision + } + + /** + * @notice This function serves exactly the same as invoke(Invocation[] memory invocations), + * but includes logic to handle the highly packed calldata + * @dev Fallback eliminates the need to include function sig in calldata + * @param input Packed data to pass to invoke logic + * @return required no-op + */ + fallback (bytes calldata input) external returns (bytes memory) { + _decodeFallbackAndInvoke(input); + return ""; + } + + /** + * @notice Processes invocation with highly packed data + * @dev + * Encoding Scheme: + * [0:1] => uint action + * [1:2] => uint length of current encoded type + * [2:length] => current encoded type (see individual type decoding functions) + * @param input Packed data to pass to invoke logic + */ + function _decodeFallbackAndInvoke(bytes calldata input) internal { + PTR memory ptr; + + while (ptr.pos < input.length) { + uint8 action = _readUint8(input, ptr); + + if (action == 1) { // DEPOSIT + (address account, address product, UFixed18 amount) = + (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _deposit(account, IProduct(product), amount); + + } else if (action == 2) { // WITHDRAW + (address receiver, address product, UFixed18 amount) = + (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _withdraw(receiver, IProduct(product), amount); + + } else if (action == 3) { // OPEN_TAKE + (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _openTake(IProduct(product), amount); + + } else if (action == 4) { // CLOSE_TAKE + (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _closeTake(IProduct(product), amount); + + } else if (action == 5) { // OPEN_MAKE + (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _openMake(IProduct(product), amount); + + } else if (action == 6) { // CLOSE_MAKE + (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _closeMake(IProduct(product), amount); + + } else if (action == 7) { // CLAIM + (address product, uint256[] memory programIds) = + (_readAndCacheAddress(input, ptr), _readUint256Array(input, ptr)); + _claim(IProduct(product), programIds); + + } else if (action == 8) { // WRAP + (address receiver, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _wrap(receiver, amount); + + } else if (action == 9) { // UNWRAP + (address receiver, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _unwrap(receiver, amount); + + } else if (action == 10) { // WRAP_AND_DEPOSIT + (address account, address product, UFixed18 amount) = + (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _wrapAndDeposit(account, IProduct(product), amount); + + } else if (action == 11) { // WITHDRAW_AND_UNWRAP + (address receiver, address product, UFixed18 amount) = + (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _withdrawAndUnwrap(receiver, IProduct(product), amount); + + } else if (action == 12) { // VAULT_DEPOSIT + (address depositer, address vault, UFixed18 amount) = + (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _vaultDeposit(depositer, IPerennialVault(vault), amount); + + } else if (action == 13) { // VAULT_REDEEM + (address vault, UFixed18 shares) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _vaultRedeem(IPerennialVault(vault), shares); + + } else if (action == 14) { // VAULT_CLAIM + (address owner, address vault) = (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr)); + _vaultClaim(IPerennialVault(vault), owner); + + } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT + (address account, address vault, UFixed18 amount) = + (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + _vaultWrapAndDeposit(account, IPerennialVault(vault), amount); + } + } + } + + /** + * @notice Unchecked sets address in cache + * @param value Address to add to cache + */ + function _cacheAddress(address value) private { + uint256 index = addressCache.length; + addressCache.push(value); + addressLookup[value] = index; + + emit AddressAddedToCache(value, index); + } + + /** + * @notice Helper function to get address from calldata + * @param input Full calldata payload + * @param ptr Current index of input to start decoding + * @return result The decoded address + */ + function _readAndCacheAddress(bytes calldata input, PTR memory ptr) private returns (address result) { + uint8 len = _readUint8(input, ptr); + + // user is new to registry, add next 20 bytes as address to registry and return address + if (len == 0) { + result = _bytesToAddress(input[ptr.pos:ptr.pos + ADDRESS_LENGTH]); + ptr.pos += ADDRESS_LENGTH; + + _cacheAddress(result); + } else { + uint256 idx = _bytesToUint256(input[ptr.pos:ptr.pos + len]); + ptr.pos += len; + + result = _lookupAddress(idx); + } + } + + /** + * @notice Checked gets the address in cache mapped to the cache index + * @dev There is an issue with the calldata if a txn uses cache before caching address + * @param index The cache index + * @return result Address stored at cache index + */ + function _lookupAddress(uint256 index) private view returns (address result) { + result = addressCache[index]; + if (result == address(0)) revert MultiInvokerRollupAddressIndexOutOfBoundsError(); + } + + /** + * @notice Wraps next length of bytes as UFixed18 + * @param input Full calldata payload + * @param ptr Current index of input to start decoding + * @param ptr Current index of input to start decoding + */ + function _readUFixed18(bytes calldata input, PTR memory ptr) private pure returns (UFixed18 result) { + return UFixed18.wrap(_readUint256(input, ptr)); + } + + /** + * @notice Unpacks next length of bytes as lengths of bytes into array of uint256 + * @param input Full calldata payload + * @param ptr Current index of input to start decoding + * @return result ProgramIds for CLAIM action + */ + function _readUint256Array(bytes calldata input, PTR memory ptr) private pure returns (uint256[] memory result) { + uint8 arrayLen = _readUint8(input, ptr); + + result = new uint256[](arrayLen); + for (uint256 i; i < arrayLen; i++) { + result[i] = _readUint256(input, ptr); + } + } + + /** + * @notice Helper function to get uint8 length from calldata + * @param input Full calldata payload + * @param ptr Current index of input to start decoding + * @return result The decoded uint8 length + */ + function _readUint8(bytes calldata input, PTR memory ptr) private pure returns (uint8 result) { + result = _bytesToUint8(input[ptr.pos:ptr.pos + UINT8_LENGTH]); + ptr.pos += UINT8_LENGTH; + } + + /** + * @notice Helper function to get uint256 from calldata + * @param input Full calldata payload + * @param ptr Current index of input to start decoding + * @return result The decoded uint256 + */ + function _readUint256(bytes calldata input, PTR memory ptr) private pure returns (uint256 result) { + uint8 len = _readUint8(input, ptr); + if (len > UINT256_LENGTH) revert MultiInvokerRollupInvalidUint256LengthError(); + + result = _bytesToUint256(input[ptr.pos:ptr.pos + len]); + ptr.pos += len; + } + + /** + * @notice Implementation of GNSPS' standard BytesLib.sol + * @param input 1 byte slice to convert to uint8 to decode lengths + * @return result The uint8 representation of input + */ + function _bytesToUint8(bytes memory input) private pure returns (uint8 result) { + assembly { + result := mload(add(input, UINT8_LENGTH)) + } + } + + /** + * @dev This is called in decodeAccount and decodeProduct which both only pass 20 byte slices + * @notice Unchecked force of 20 bytes into address + * @param input The 20 bytes to be converted to address + * @return result Address representation of `input` + */ + function _bytesToAddress(bytes memory input) private pure returns (address result) { + assembly { + result := mload(add(input, ADDRESS_LENGTH)) + } + } + + /** + * @notice Unchecked loads arbitrarily-sized bytes into a uint + * @dev Bytes length enforced as < max word size + * @param input The bytes to convert to uint256 + * @return result The resulting uint256 + */ + function _bytesToUint256(bytes memory input) private pure returns (uint256 result) { + uint256 len = input.length; + + assembly { + result := mload(add(input, UINT256_LENGTH)) + } + + // readable right shift to change right padding of mload to left padding + result >>= (UINT256_LENGTH - len) * 8; + } +} diff --git a/packages/perennial/deploy/004_deploy_multiinvoker.ts b/packages/perennial/deploy/004_deploy_multiinvoker.ts index e484bfa0..d034650a 100644 --- a/packages/perennial/deploy/004_deploy_multiinvoker.ts +++ b/packages/perennial/deploy/004_deploy_multiinvoker.ts @@ -2,8 +2,14 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types' import { DeployFunction } from 'hardhat-deploy/types' import { Deployment } from 'hardhat-deploy/dist/types' import { getMultisigAddress } from '../../common/testutil/constants' -import { Controller__factory, IERC20__factory, MultiInvoker__factory } from '../types/generated' +import { + Controller__factory, + IERC20__factory, + MultiInvokerRollup__factory, + MultiInvoker__factory, +} from '../types/generated' import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { isRollup } from '../../common/testutil/network' const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts, ethers } = hre @@ -34,8 +40,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const usdc = await IERC20__factory.connect(usdcAddress, deployerSigner) + const rollup = isRollup(networkName) + const contractName = rollup ? 'MultiInvokerRollup' : 'MultiInvoker' + const multiInvokerImpl: Deployment = await deploy('MultiInvoker_Impl', { - contract: 'MultiInvoker', + contract: contractName, args: [usdcAddress, batcherAddress, reserveAddress, controllerAddress], from: deployer, skipIfAlreadyDeployed: true, @@ -53,7 +62,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }) // INITIALIZE - const multiInvoker = await new MultiInvoker__factory(deployerSigner).attach((await get('MultiInvoker_Proxy')).address) + let multiInvoker: any + if (!rollup) { + multiInvoker = await new MultiInvoker__factory(deployerSigner).attach((await get('MultiInvoker_Proxy')).address) + } else { + multiInvoker = await new MultiInvokerRollup__factory(deployerSigner).attach( + ( + await get('MultiInvoker_Proxy') + ).address, + ) + } if ((await usdc.callStatic.allowance(multiInvoker.address, reserveAddress)).eq(ethers.constants.MaxUint256)) { console.log('MultiInvoker already initialized.') diff --git a/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Impl.json b/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Impl.json index 3742a83e..061c7ef3 100644 --- a/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Impl.json +++ b/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Impl.json @@ -1,32 +1,37 @@ { - "address": "0xE77076D3EeE12dA1d7402Ff4e6Ca12A8d99FcE8B", + "address": "0x8D89B54276E50E8400d51aec2312340Fd0e4c006", "abi": [ { "inputs": [ { "internalType": "Token6", - "name": "usdc_", + "name": "usdc", "type": "address" }, { "internalType": "contract IBatcher", - "name": "batcher_", + "name": "_batcher", "type": "address" }, { "internalType": "contract IEmptySetReserve", - "name": "reserve_", + "name": "_reserve", "type": "address" }, { "internalType": "contract IController", - "name": "controller_", + "name": "_controller", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "MultiInvokerRollupInvalidCalldataError", + "type": "error" + }, { "inputs": [ { @@ -48,6 +53,25 @@ "name": "UInitializableZeroVersionError", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "AddressAddedToCache", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -61,6 +85,10 @@ "name": "Initialized", "type": "event" }, + { + "stateMutability": "nonpayable", + "type": "fallback" + }, { "inputs": [], "name": "DSU", @@ -87,6 +115,44 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "addressCache", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "addressLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "batcher", @@ -172,19 +238,33 @@ "type": "function" } ], - "transactionHash": "0xa18e091d95eeb9c5ba63486e5528be752aa4aaea0e4597d802f6e05202176a09", + "transactionHash": "0x857ae23904225cd252db3b4c5dd4a07cd4c8c9e3f40e8c0fca36f163434ed284", "receipt": { "to": null, - "from": "0x66a7fDB96C583c59597de16d8b2B989231415339", - "contractAddress": "0xE77076D3EeE12dA1d7402Ff4e6Ca12A8d99FcE8B", + "from": "0x2aF0AE203e2Fa0710EAB8D25884F8aa723517B69", + "contractAddress": "0x8D89B54276E50E8400d51aec2312340Fd0e4c006", "transactionIndex": 1, - "gasUsed": "2029842", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa12cc12563f68f779f129fdb0baf4ff8fe9895d2b61077fc5ba60c94bee99570", - "transactionHash": "0xa18e091d95eeb9c5ba63486e5528be752aa4aaea0e4597d802f6e05202176a09", - "logs": [], - "blockNumber": 4214001, - "cumulativeGasUsed": "2029842", + "gasUsed": "28664199", + "logsBloom": "0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000200000000040000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000004000000000000000000000000000000000000000", + "blockHash": "0x0ef6a1e2946fed8a91c8b132c7ec4ea30119a5744b1d79d92874cd7f6c866e68", + "transactionHash": "0x857ae23904225cd252db3b4c5dd4a07cd4c8c9e3f40e8c0fca36f163434ed284", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 14355090, + "transactionHash": "0x857ae23904225cd252db3b4c5dd4a07cd4c8c9e3f40e8c0fca36f163434ed284", + "address": "0x8D89B54276E50E8400d51aec2312340Fd0e4c006", + "topics": [ + "0xd9643d04a6ca8b6a112ed2bb7b77a6087a6d23739fb4cfd7c813fb3a001c3096", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 0, + "blockHash": "0x0ef6a1e2946fed8a91c8b132c7ec4ea30119a5744b1d79d92874cd7f6c866e68" + } + ], + "blockNumber": 14355090, + "cumulativeGasUsed": "28664199", "status": 1, "byzantium": true }, @@ -194,23 +274,21 @@ "0x0d49c416103Cbd276d9c3cd96710dB264e3A0c27", "0x6cF1A4373ba7D10bC37fAeC4694807B626B7f161" ], - "numDeployments": 1, - "solcInputHash": "0954eb4c5a9afab2c0aa2d884eb92458", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"Token6\",\"name\":\"usdc_\",\"type\":\"address\"},{\"internalType\":\"contract IBatcher\",\"name\":\"batcher_\",\"type\":\"address\"},{\"internalType\":\"contract IEmptySetReserve\",\"name\":\"reserve_\",\"type\":\"address\"},{\"internalType\":\"contract IController\",\"name\":\"controller_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"UInitializableAlreadyInitializedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UInitializableNotInitializingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UInitializableZeroVersionError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DSU\",\"outputs\":[{\"internalType\":\"Token18\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDC\",\"outputs\":[{\"internalType\":\"Token6\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batcher\",\"outputs\":[{\"internalType\":\"contract IBatcher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract ICollateral\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum IMultiInvoker.PerennialAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"args\",\"type\":\"bytes\"}],\"internalType\":\"struct IMultiInvoker.Invocation[]\",\"name\":\"invocations\",\"type\":\"tuple[]\"}],\"name\":\"invoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reserve\",\"outputs\":[{\"internalType\":\"contract IEmptySetReserve\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Called at implementation instantiate and constant for that implementation.\",\"params\":{\"batcher_\":\"Protocol Batcher address\",\"controller_\":\"Protocol Controller address\",\"reserve_\":\"EmptySet Reserve address\",\"usdc_\":\"USDC stablecoin address\"}},\"initialize()\":{\"details\":\"Must be called atomically as part of the upgradeable proxy deployment to avoid front-running\"},\"invoke((uint8,bytes)[])\":{\"params\":{\"invocations\":\"The list of invocations to execute in order\"}}},\"stateVariables\":{\"DSU\":{\"details\":\"DSU address\"},\"USDC\":{\"details\":\"USDC stablecoin address\"},\"batcher\":{\"details\":\"Batcher address\"},\"collateral\":{\"details\":\"Collateral address\"},\"controller\":{\"details\":\"Controller address\"},\"reserve\":{\"details\":\"Reserve address\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Initializes the immutable contract state\"},\"initialize()\":{\"notice\":\"Initializes the contract state\"},\"invoke((uint8,bytes)[])\":{\"notice\":\"Executes a list of invocations in order\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/multiinvoker/MultiInvoker.sol\":\"MultiInvoker\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"../interfaces/IEmptySetReserve.sol\\\";\\n\\ninterface IBatcher {\\n event Wrap(address indexed to, UFixed18 amount);\\n event Unwrap(address indexed to, UFixed18 amount);\\n event Rebalance(UFixed18 newMinted, UFixed18 newRedeemed);\\n event Close(UFixed18 amount);\\n\\n error BatcherNotImplementedError();\\n error BatcherBalanceMismatchError(UFixed18 oldBalance, UFixed18 newBalance);\\n\\n function RESERVE() external view returns (IEmptySetReserve); // solhint-disable-line func-name-mixedcase\\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\\n function totalBalance() external view returns (UFixed18);\\n function wrap(UFixed18 amount, address to) external;\\n function unwrap(UFixed18 amount, address to) external;\\n function rebalance() external;\\n}\\n\",\"keccak256\":\"0xb9c0b0fc0dfcd44492b029ede04d304f6906b030cb925dc0fc2579e8c58d9734\",\"license\":\"Apache-2.0\"},\"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\ninterface IEmptySetReserve {\\n event Redeem(address indexed account, uint256 costAmount, uint256 redeemAmount);\\n event Mint(address indexed account, uint256 mintAmount, uint256 costAmount);\\n event Repay(address indexed account, uint256 repayAmount);\\n\\n function debt(address borrower) external view returns (UFixed18);\\n function repay(address borrower, UFixed18 amount) external;\\n function mint(UFixed18 amount) external;\\n function redeem(UFixed18 amount) external;\\n}\\n\",\"keccak256\":\"0xdb96e26082a471c7803e892ecd8d2877f23cd9e31f13a3e407dd5f8909078864\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\n\\ninterface IOracleProvider {\\n /// @dev Error for invalid oracle round\\n error InvalidOracleRound();\\n\\n /// @dev A singular oracle version with its corresponding data\\n struct OracleVersion {\\n /// @dev The iterative version\\n uint256 version;\\n\\n /// @dev the timestamp of the oracle update\\n uint256 timestamp;\\n\\n /// @dev The oracle price of the corresponding version\\n Fixed18 price;\\n }\\n\\n function sync() external returns (OracleVersion memory);\\n function currentVersion() external view returns (OracleVersion memory);\\n function atVersion(uint256 oracleVersion) external view returns (OracleVersion memory);\\n}\\n\",\"keccak256\":\"0x11e8ebb40917dcce08a6366e6fa8d25b037552d4ea66b96c13e6f45b1f817c52\",\"license\":\"Apache-2.0\"},\"@equilibria/root/control/unstructured/UInitializable.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../../storage/UStorage.sol\\\";\\n\\n/**\\n * @title UInitializable\\n * @notice Library to manage the initialization lifecycle of upgradeable contracts\\n * @dev `UInitializable` allows the creation of pseudo-constructors for upgradeable contracts. One\\n * `initializer` should be declared per top-level contract. Child contracts can use the `onlyInitializer`\\n * modifier to tag their internal initialization functions to ensure that they can only be called\\n * from a top-level `initializer` or a constructor.\\n */\\nabstract contract UInitializable {\\n error UInitializableZeroVersionError();\\n error UInitializableAlreadyInitializedError(uint256 version);\\n error UInitializableNotInitializingError();\\n\\n event Initialized(uint256 version);\\n\\n /// @dev The initialized flag\\n Uint256Storage private constant _version = Uint256Storage.wrap(keccak256(\\\"equilibria.root.UInitializable.version\\\"));\\n\\n /// @dev The initializing flag\\n BoolStorage private constant _initializing = BoolStorage.wrap(keccak256(\\\"equilibria.root.UInitializable.initializing\\\"));\\n\\n /// @dev Can only be called once per version, `version` is 1-indexed\\n modifier initializer(uint256 version) {\\n if (version == 0) revert UInitializableZeroVersionError();\\n if (_version.read() >= version) revert UInitializableAlreadyInitializedError(version);\\n\\n _version.store(version);\\n _initializing.store(true);\\n\\n _;\\n\\n _initializing.store(false);\\n emit Initialized(version);\\n }\\n\\n /// @dev Can only be called from an initializer or constructor\\n modifier onlyInitializer() {\\n if (!_constructing() && !_initializing.read()) revert UInitializableNotInitializingError();\\n _;\\n }\\n\\n /**\\n * @notice Returns whether the contract is currently being constructed\\n * @dev {Address.isContract} returns false for contracts currently in the process of being constructed\\n * @return Whether the contract is currently being constructed\\n */\\n function _constructing() private view returns (bool) {\\n return !Address.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd2743d8fcc220ed2ccdc0bba1db0a3e107741bd5c0cac47ca8c0b5a00ba2fd7f\",\"license\":\"Apache-2.0\"},\"@equilibria/root/curve/CurveMath.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../number/types/UFixed18.sol\\\";\\nimport \\\"../number/types/Fixed18.sol\\\";\\n\\n/**\\n * @title CurveMath\\n * @notice Library for managing math operations for utilization curves.\\n */\\nlibrary CurveMath {\\n error CurveMathOutOfBoundsError();\\n\\n /**\\n * @notice Computes a linear interpolation between two points\\n * @param startX First point's x-coordinate\\n * @param startY First point's y-coordinate\\n * @param endX Second point's x-coordinate\\n * @param endY Second point's y-coordinate\\n * @param targetX x-coordinate to interpolate\\n * @return y-coordinate for `targetX` along the line from (`startX`, `startY`) -> (`endX`, `endY`)\\n */\\n function linearInterpolation(\\n UFixed18 startX,\\n Fixed18 startY,\\n UFixed18 endX,\\n Fixed18 endY,\\n UFixed18 targetX\\n ) internal pure returns (Fixed18) {\\n if (targetX.lt(startX) || targetX.gt(endX)) revert CurveMathOutOfBoundsError();\\n\\n UFixed18 xRange = endX.sub(startX);\\n Fixed18 yRange = endY.sub(startY);\\n UFixed18 xRatio = targetX.sub(startX).div(xRange);\\n return yRange.mul(Fixed18Lib.from(xRatio)).add(startY);\\n }\\n}\\n\",\"keccak256\":\"0x60d159f9ddf0dbe81124ecad58bba734b4cf82877637ff8d9d7f3e92f2da4ded\",\"license\":\"Apache-2.0\"},\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../CurveMath.sol\\\";\\nimport \\\"../../number/types/PackedUFixed18.sol\\\";\\nimport \\\"../../number/types/PackedFixed18.sol\\\";\\n\\n/// @dev JumpRateUtilizationCurve type\\nstruct JumpRateUtilizationCurve {\\n PackedFixed18 minRate;\\n PackedFixed18 maxRate;\\n PackedFixed18 targetRate;\\n PackedUFixed18 targetUtilization;\\n}\\nusing JumpRateUtilizationCurveLib for JumpRateUtilizationCurve global;\\ntype JumpRateUtilizationCurveStorage is bytes32;\\nusing JumpRateUtilizationCurveStorageLib for JumpRateUtilizationCurveStorage global;\\n\\n/**\\n * @title JumpRateUtilizationCurveLib\\n * @notice Library for the Jump Rate utilization curve type\\n */\\nlibrary JumpRateUtilizationCurveLib {\\n /**\\n * @notice Computes the corresponding rate for a utilization ratio\\n * @param utilization The utilization ratio\\n * @return The corresponding rate\\n */\\n function compute(JumpRateUtilizationCurve memory self, UFixed18 utilization) internal pure returns (Fixed18) {\\n UFixed18 targetUtilization = self.targetUtilization.unpack();\\n if (utilization.lt(targetUtilization)) {\\n return CurveMath.linearInterpolation(\\n UFixed18Lib.ZERO,\\n self.minRate.unpack(),\\n targetUtilization,\\n self.targetRate.unpack(),\\n utilization\\n );\\n }\\n if (utilization.lt(UFixed18Lib.ONE)) {\\n return CurveMath.linearInterpolation(\\n targetUtilization,\\n self.targetRate.unpack(),\\n UFixed18Lib.ONE,\\n self.maxRate.unpack(),\\n utilization\\n );\\n }\\n return self.maxRate.unpack();\\n }\\n}\\n\\nlibrary JumpRateUtilizationCurveStorageLib {\\n function read(JumpRateUtilizationCurveStorage self) internal view returns (JumpRateUtilizationCurve memory) {\\n return _storagePointer(self);\\n }\\n\\n function store(JumpRateUtilizationCurveStorage self, JumpRateUtilizationCurve memory value) internal {\\n JumpRateUtilizationCurve storage storagePointer = _storagePointer(self);\\n\\n storagePointer.minRate = value.minRate;\\n storagePointer.maxRate = value.maxRate;\\n storagePointer.targetRate = value.targetRate;\\n storagePointer.targetUtilization = value.targetUtilization;\\n }\\n\\n function _storagePointer(JumpRateUtilizationCurveStorage self)\\n private pure returns (JumpRateUtilizationCurve storage pointer) {\\n assembly { pointer.slot := self }\\n }\\n}\",\"keccak256\":\"0xae202813874bc306d51b3dab8194c86f6483bb20bf1f673ddaee16aa8de567ff\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/Fixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/SignedMath.sol\\\";\\nimport \\\"./UFixed18.sol\\\";\\nimport \\\"./PackedFixed18.sol\\\";\\n\\n/// @dev Fixed18 type\\ntype Fixed18 is int256;\\nusing Fixed18Lib for Fixed18 global;\\ntype Fixed18Storage is bytes32;\\nusing Fixed18StorageLib for Fixed18Storage global;\\n\\n/**\\n * @title Fixed18Lib\\n * @notice Library for the signed fixed-decimal type.\\n */\\nlibrary Fixed18Lib {\\n error Fixed18OverflowError(uint256 value);\\n error Fixed18PackingOverflowError(int256 value);\\n error Fixed18PackingUnderflowError(int256 value);\\n\\n int256 private constant BASE = 1e18;\\n Fixed18 public constant ZERO = Fixed18.wrap(0);\\n Fixed18 public constant ONE = Fixed18.wrap(BASE);\\n Fixed18 public constant NEG_ONE = Fixed18.wrap(-1 * BASE);\\n Fixed18 public constant MAX = Fixed18.wrap(type(int256).max);\\n Fixed18 public constant MIN = Fixed18.wrap(type(int256).min);\\n\\n /**\\n * @notice Creates a signed fixed-decimal from an unsigned fixed-decimal\\n * @param a Unsigned fixed-decimal\\n * @return New signed fixed-decimal\\n */\\n function from(UFixed18 a) internal pure returns (Fixed18) {\\n uint256 value = UFixed18.unwrap(a);\\n if (value > uint256(type(int256).max)) revert Fixed18OverflowError(value);\\n return Fixed18.wrap(int256(value));\\n }\\n\\n /**\\n * @notice Creates a signed fixed-decimal from a sign and an unsigned fixed-decimal\\n * @param s Sign\\n * @param m Unsigned fixed-decimal magnitude\\n * @return New signed fixed-decimal\\n */\\n function from(int256 s, UFixed18 m) internal pure returns (Fixed18) {\\n if (s > 0) return from(m);\\n if (s < 0) return Fixed18.wrap(-1 * Fixed18.unwrap(from(m)));\\n return ZERO;\\n }\\n\\n /**\\n * @notice Creates a signed fixed-decimal from a signed integer\\n * @param a Signed number\\n * @return New signed fixed-decimal\\n */\\n function from(int256 a) internal pure returns (Fixed18) {\\n return Fixed18.wrap(a * BASE);\\n }\\n\\n /**\\n * @notice Creates a packed signed fixed-decimal from an signed fixed-decimal\\n * @param a signed fixed-decimal\\n * @return New packed signed fixed-decimal\\n */\\n function pack(Fixed18 a) internal pure returns (PackedFixed18) {\\n int256 value = Fixed18.unwrap(a);\\n if (value > type(int128).max) revert Fixed18PackingOverflowError(value);\\n if (value < type(int128).min) revert Fixed18PackingUnderflowError(value);\\n return PackedFixed18.wrap(int128(value));\\n }\\n\\n /**\\n * @notice Returns whether the signed fixed-decimal is equal to zero.\\n * @param a Signed fixed-decimal\\n * @return Whether the signed fixed-decimal is zero.\\n */\\n function isZero(Fixed18 a) internal pure returns (bool) {\\n return Fixed18.unwrap(a) == 0;\\n }\\n\\n /**\\n * @notice Adds two signed fixed-decimals `a` and `b` together\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Resulting summed signed fixed-decimal\\n */\\n function add(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) + Fixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Subtracts signed fixed-decimal `b` from `a`\\n * @param a Signed fixed-decimal to subtract from\\n * @param b Signed fixed-decimal to subtract\\n * @return Resulting subtracted signed fixed-decimal\\n */\\n function sub(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) - Fixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Multiplies two signed fixed-decimals `a` and `b` together\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Resulting multiplied signed fixed-decimal\\n */\\n function mul(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / BASE);\\n }\\n\\n /**\\n * @notice Divides signed fixed-decimal `a` by `b`\\n * @param a Signed fixed-decimal to divide\\n * @param b Signed fixed-decimal to divide by\\n * @return Resulting divided signed fixed-decimal\\n */\\n function div(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) * BASE / Fixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Divides unsigned fixed-decimal `a` by `b`\\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0`, `MAX` for `n/0`, and `MIN` for `-n/0`.\\n * @param a Unsigned fixed-decimal to divide\\n * @param b Unsigned fixed-decimal to divide by\\n * @return Resulting divided unsigned fixed-decimal\\n */\\n function unsafeDiv(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n if (isZero(b)) {\\n if (gt(a, ZERO)) return MAX;\\n if (lt(a, ZERO)) return MIN;\\n return ONE;\\n } else {\\n return div(a, b);\\n }\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First signed fixed-decimal\\n * @param b Signed number to multiply by\\n * @param c Signed number to divide by\\n * @return Resulting computation\\n */\\n function muldiv(Fixed18 a, int256 b, int256 c) internal pure returns (Fixed18) {\\n return muldiv(a, Fixed18.wrap(b), Fixed18.wrap(c));\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First signed fixed-decimal\\n * @param b Signed fixed-decimal to multiply by\\n * @param c Signed fixed-decimal to divide by\\n * @return Resulting computation\\n */\\n function muldiv(Fixed18 a, Fixed18 b, Fixed18 c) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / Fixed18.unwrap(c));\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is equal to `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is equal to `b`\\n */\\n function eq(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 1;\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is greater than `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is greater than `b`\\n */\\n function gt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 2;\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is less than `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is less than `b`\\n */\\n function lt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 0;\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is greater than or equal to `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is greater than or equal to `b`\\n */\\n function gte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return gt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is less than or equal to `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is less than or equal to `b`\\n */\\n function lte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return lt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Compares the signed fixed-decimals `a` and `b`\\n * @dev Returns: 2 for greater than\\n * 1 for equal to\\n * 0 for less than\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Compare result of `a` and `b`\\n */\\n function compare(Fixed18 a, Fixed18 b) internal pure returns (uint256) {\\n (int256 au, int256 bu) = (Fixed18.unwrap(a), Fixed18.unwrap(b));\\n if (au > bu) return 2;\\n if (au < bu) return 0;\\n return 1;\\n }\\n\\n /**\\n * @notice Returns a signed fixed-decimal representing the ratio of `a` over `b`\\n * @param a First signed number\\n * @param b Second signed number\\n * @return Ratio of `a` over `b`\\n */\\n function ratio(int256 a, int256 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(a * BASE / b);\\n }\\n\\n /**\\n * @notice Returns the minimum of signed fixed-decimals `a` and `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Minimum of `a` and `b`\\n */\\n function min(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(SignedMath.min(Fixed18.unwrap(a), Fixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Returns the maximum of signed fixed-decimals `a` and `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Maximum of `a` and `b`\\n */\\n function max(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(SignedMath.max(Fixed18.unwrap(a), Fixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Converts the signed fixed-decimal into an integer, truncating any decimal portion\\n * @param a Signed fixed-decimal\\n * @return Truncated signed number\\n */\\n function truncate(Fixed18 a) internal pure returns (int256) {\\n return Fixed18.unwrap(a) / BASE;\\n }\\n\\n /**\\n * @notice Returns the sign of the signed fixed-decimal\\n * @dev Returns: -1 for negative\\n * 0 for zero\\n * 1 for positive\\n * @param a Signed fixed-decimal\\n * @return Sign of the signed fixed-decimal\\n */\\n function sign(Fixed18 a) internal pure returns (int256) {\\n if (Fixed18.unwrap(a) > 0) return 1;\\n if (Fixed18.unwrap(a) < 0) return -1;\\n return 0;\\n }\\n\\n /**\\n * @notice Returns the absolute value of the signed fixed-decimal\\n * @param a Signed fixed-decimal\\n * @return Absolute value of the signed fixed-decimal\\n */\\n function abs(Fixed18 a) internal pure returns (UFixed18) {\\n return UFixed18.wrap(SignedMath.abs(Fixed18.unwrap(a)));\\n }\\n}\\n\\nlibrary Fixed18StorageLib {\\n function read(Fixed18Storage self) internal view returns (Fixed18 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(Fixed18Storage self, Fixed18 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x613587461ef3437ef33229cdda7d34ea746278721baf06e20b2e43977f43174d\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/PackedFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./Fixed18.sol\\\";\\n\\n/// @dev PackedFixed18 type\\ntype PackedFixed18 is int128;\\nusing PackedFixed18Lib for PackedFixed18 global;\\n\\n/**\\n * @title PackedFixed18Lib\\n * @dev A packed version of the Fixed18 which takes up half the storage space (two PackedFixed18 can be packed\\n * into a single slot). Only valid within the range -1.7014118e+20 <= x <= 1.7014118e+20.\\n * @notice Library for the packed signed fixed-decimal type.\\n */\\nlibrary PackedFixed18Lib {\\n PackedFixed18 public constant MAX = PackedFixed18.wrap(type(int128).max);\\n PackedFixed18 public constant MIN = PackedFixed18.wrap(type(int128).min);\\n\\n /**\\n * @notice Creates an unpacked signed fixed-decimal from a packed signed fixed-decimal\\n * @param self packed signed fixed-decimal\\n * @return New unpacked signed fixed-decimal\\n */\\n function unpack(PackedFixed18 self) internal pure returns (Fixed18) {\\n return Fixed18.wrap(int256(PackedFixed18.unwrap(self)));\\n }\\n}\\n\",\"keccak256\":\"0xb52960cc8e3132e45d342bbbb1c6a96219022cd8557997933bd8250170268b64\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/PackedUFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./UFixed18.sol\\\";\\n\\n/// @dev PackedUFixed18 type\\ntype PackedUFixed18 is uint128;\\nusing PackedUFixed18Lib for PackedUFixed18 global;\\n\\n/**\\n * @title PackedUFixed18Lib\\n * @dev A packed version of the UFixed18 which takes up half the storage space (two PackedUFixed18 can be packed\\n * into a single slot). Only valid within the range 0 <= x <= 3.4028237e+20.\\n * @notice Library for the packed unsigned fixed-decimal type.\\n */\\nlibrary PackedUFixed18Lib {\\n PackedUFixed18 public constant MAX = PackedUFixed18.wrap(type(uint128).max);\\n\\n /**\\n * @notice Creates an unpacked unsigned fixed-decimal from a packed unsigned fixed-decimal\\n * @param self packed unsigned fixed-decimal\\n * @return New unpacked unsigned fixed-decimal\\n */\\n function unpack(PackedUFixed18 self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(PackedUFixed18.unwrap(self)));\\n }\\n}\\n\",\"keccak256\":\"0xb5c5cd32d6530b2fe75228b6be32ebcb7762f6d7988b85a6b85a289ce8256d51\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/UFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"./Fixed18.sol\\\";\\nimport \\\"./PackedUFixed18.sol\\\";\\n\\n/// @dev UFixed18 type\\ntype UFixed18 is uint256;\\nusing UFixed18Lib for UFixed18 global;\\ntype UFixed18Storage is bytes32;\\nusing UFixed18StorageLib for UFixed18Storage global;\\n\\n/**\\n * @title UFixed18Lib\\n * @notice Library for the unsigned fixed-decimal type.\\n */\\nlibrary UFixed18Lib {\\n error UFixed18UnderflowError(int256 value);\\n error UFixed18PackingOverflowError(uint256 value);\\n\\n uint256 private constant BASE = 1e18;\\n UFixed18 public constant ZERO = UFixed18.wrap(0);\\n UFixed18 public constant ONE = UFixed18.wrap(BASE);\\n UFixed18 public constant MAX = UFixed18.wrap(type(uint256).max);\\n\\n /**\\n * @notice Creates a unsigned fixed-decimal from a signed fixed-decimal\\n * @param a Signed fixed-decimal\\n * @return New unsigned fixed-decimal\\n */\\n function from(Fixed18 a) internal pure returns (UFixed18) {\\n int256 value = Fixed18.unwrap(a);\\n if (value < 0) revert UFixed18UnderflowError(value);\\n return UFixed18.wrap(uint256(value));\\n }\\n\\n /**\\n * @notice Creates a unsigned fixed-decimal from a unsigned integer\\n * @param a Unsigned number\\n * @return New unsigned fixed-decimal\\n */\\n function from(uint256 a) internal pure returns (UFixed18) {\\n return UFixed18.wrap(a * BASE);\\n }\\n\\n /**\\n * @notice Creates a packed unsigned fixed-decimal from an unsigned fixed-decimal\\n * @param a unsigned fixed-decimal\\n * @return New packed unsigned fixed-decimal\\n */\\n function pack(UFixed18 a) internal pure returns (PackedUFixed18) {\\n uint256 value = UFixed18.unwrap(a);\\n if (value > type(uint128).max) revert UFixed18PackingOverflowError(value);\\n return PackedUFixed18.wrap(uint128(value));\\n }\\n\\n /**\\n * @notice Returns whether the unsigned fixed-decimal is equal to zero.\\n * @param a Unsigned fixed-decimal\\n * @return Whether the unsigned fixed-decimal is zero.\\n */\\n function isZero(UFixed18 a) internal pure returns (bool) {\\n return UFixed18.unwrap(a) == 0;\\n }\\n\\n /**\\n * @notice Adds two unsigned fixed-decimals `a` and `b` together\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Resulting summed unsigned fixed-decimal\\n */\\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Subtracts unsigned fixed-decimal `b` from `a`\\n * @param a Unsigned fixed-decimal to subtract from\\n * @param b Unsigned fixed-decimal to subtract\\n * @return Resulting subtracted unsigned fixed-decimal\\n */\\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Multiplies two unsigned fixed-decimals `a` and `b` together\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Resulting multiplied unsigned fixed-decimal\\n */\\n function mul(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / BASE);\\n }\\n\\n /**\\n * @notice Divides unsigned fixed-decimal `a` by `b`\\n * @param a Unsigned fixed-decimal to divide\\n * @param b Unsigned fixed-decimal to divide by\\n * @return Resulting divided unsigned fixed-decimal\\n */\\n function div(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) * BASE / UFixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Divides unsigned fixed-decimal `a` by `b`\\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0` and `MAX` for `n/0`.\\n * @param a Unsigned fixed-decimal to divide\\n * @param b Unsigned fixed-decimal to divide by\\n * @return Resulting divided unsigned fixed-decimal\\n */\\n function unsafeDiv(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n if (isZero(b)) {\\n return isZero(a) ? ONE : MAX;\\n } else {\\n return div(a, b);\\n }\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First unsigned fixed-decimal\\n * @param b Unsigned number to multiply by\\n * @param c Unsigned number to divide by\\n * @return Resulting computation\\n */\\n function muldiv(UFixed18 a, uint256 b, uint256 c) internal pure returns (UFixed18) {\\n return muldiv(a, UFixed18.wrap(b), UFixed18.wrap(c));\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First unsigned fixed-decimal\\n * @param b Unsigned fixed-decimal to multiply by\\n * @param c Unsigned fixed-decimal to divide by\\n * @return Resulting computation\\n */\\n function muldiv(UFixed18 a, UFixed18 b, UFixed18 c) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / UFixed18.unwrap(c));\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is equal to `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is equal to `b`\\n */\\n function eq(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 1;\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is greater than `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is greater than `b`\\n */\\n function gt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 2;\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is less than `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is less than `b`\\n */\\n function lt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 0;\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is greater than or equal to `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is greater than or equal to `b`\\n */\\n function gte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return gt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is less than or equal to `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is less than or equal to `b`\\n */\\n function lte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return lt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Compares the unsigned fixed-decimals `a` and `b`\\n * @dev Returns: 2 for greater than\\n * 1 for equal to\\n * 0 for less than\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Compare result of `a` and `b`\\n */\\n function compare(UFixed18 a, UFixed18 b) internal pure returns (uint256) {\\n (uint256 au, uint256 bu) = (UFixed18.unwrap(a), UFixed18.unwrap(b));\\n if (au > bu) return 2;\\n if (au < bu) return 0;\\n return 1;\\n }\\n\\n /**\\n * @notice Returns a unsigned fixed-decimal representing the ratio of `a` over `b`\\n * @param a First unsigned number\\n * @param b Second unsigned number\\n * @return Ratio of `a` over `b`\\n */\\n function ratio(uint256 a, uint256 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(a * BASE / b);\\n }\\n\\n /**\\n * @notice Returns the minimum of unsigned fixed-decimals `a` and `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Minimum of `a` and `b`\\n */\\n function min(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(Math.min(UFixed18.unwrap(a), UFixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Returns the maximum of unsigned fixed-decimals `a` and `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Maximum of `a` and `b`\\n */\\n function max(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(Math.max(UFixed18.unwrap(a), UFixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Converts the unsigned fixed-decimal into an integer, truncating any decimal portion\\n * @param a Unsigned fixed-decimal\\n * @return Truncated unsigned number\\n */\\n function truncate(UFixed18 a) internal pure returns (uint256) {\\n return UFixed18.unwrap(a) / BASE;\\n }\\n}\\n\\nlibrary UFixed18StorageLib {\\n function read(UFixed18Storage self) internal view returns (UFixed18 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(UFixed18Storage self, UFixed18 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8ebef1e6c717f565b9ed545a876b5692b4007e6485c99f39d363f7405e591792\",\"license\":\"Apache-2.0\"},\"@equilibria/root/storage/UStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../number/types/UFixed18.sol\\\";\\n\\n/// @dev Stored boolean slot\\ntype BoolStorage is bytes32;\\nusing BoolStorageLib for BoolStorage global;\\n\\n/// @dev Stored uint256 slot\\ntype Uint256Storage is bytes32;\\nusing Uint256StorageLib for Uint256Storage global;\\n\\n/// @dev Stored int256 slot\\ntype Int256Storage is bytes32;\\nusing Int256StorageLib for Int256Storage global;\\n\\n/// @dev Stored address slot\\ntype AddressStorage is bytes32;\\nusing AddressStorageLib for AddressStorage global;\\n\\n/// @dev Stored bytes32 slot\\ntype Bytes32Storage is bytes32;\\nusing Bytes32StorageLib for Bytes32Storage global;\\n\\n/**\\n * @title BoolStorageLib\\n * @notice Library to manage storage and retrival of a boolean at a fixed storage slot\\n */\\nlibrary BoolStorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored bool value\\n */\\n function read(BoolStorage self) internal view returns (bool value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value boolean value to store\\n */\\n function store(BoolStorage self, bool value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title Uint256StorageLib\\n * @notice Library to manage storage and retrival of an uint256 at a fixed storage slot\\n */\\nlibrary Uint256StorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored uint256 value\\n */\\n function read(Uint256Storage self) internal view returns (uint256 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value uint256 value to store\\n */\\n function store(Uint256Storage self, uint256 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title Int256StorageLib\\n * @notice Library to manage storage and retrival of an int256 at a fixed storage slot\\n */\\nlibrary Int256StorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored int256 value\\n */\\n function read(Int256Storage self) internal view returns (int256 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value int256 value to store\\n */\\n function store(Int256Storage self, int256 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title AddressStorageLib\\n * @notice Library to manage storage and retrival of an address at a fixed storage slot\\n */\\nlibrary AddressStorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored address value\\n */\\n function read(AddressStorage self) internal view returns (address value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value address value to store\\n */\\n function store(AddressStorage self, address value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title Bytes32StorageLib\\n * @notice Library to manage storage and retrival of a bytes32 at a fixed storage slot\\n */\\nlibrary Bytes32StorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored bytes32 value\\n */\\n function read(Bytes32Storage self) internal view returns (bytes32 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value bytes32 value to store\\n */\\n function store(Bytes32Storage self, bytes32 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe2b8491d1b5aa93f7e059e1a8f156b0ab37fef9ed973be97a64f2eabfc2cc172\",\"license\":\"Apache-2.0\"},\"@equilibria/root/token/types/Token18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"../../number/types/UFixed18.sol\\\";\\n\\n/// @dev Token18\\ntype Token18 is address;\\nusing Token18Lib for Token18 global;\\ntype Token18Storage is bytes32;\\nusing Token18StorageLib for Token18Storage global;\\n\\n/**\\n * @title Token18Lib\\n * @notice Library to manage 18-decimal ERC20s that is compliant with the fixed-decimal types.\\n * @dev Maintains significant gas savings over other Token implementations since no conversion take place\\n */\\nlibrary Token18Lib {\\n using SafeERC20 for IERC20;\\n\\n Token18 public constant ZERO = Token18.wrap(address(0));\\n\\n /**\\n * @notice Returns whether a token is the zero address\\n * @param self Token to check for\\n * @return Whether the token is the zero address\\n */\\n function isZero(Token18 self) internal pure returns (bool) {\\n return Token18.unwrap(self) == Token18.unwrap(ZERO);\\n }\\n\\n /**\\n * @notice Returns whether the two tokens are equal\\n * @param a First token to compare\\n * @param b Second token to compare\\n * @return Whether the two tokens are equal\\n */\\n function eq(Token18 a, Token18 b) internal pure returns (bool) {\\n return Token18.unwrap(a) == Token18.unwrap(b);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend infinite tokens from the caller\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n */\\n function approve(Token18 self, address grantee) internal {\\n IERC20(Token18.unwrap(self)).safeApprove(grantee, type(uint256).max);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend `amount` tokens from the caller\\n * @dev There are important race conditions to be aware of when using this function\\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n * @param amount Amount of tokens to approve to spend\\n */\\n function approve(Token18 self, address grantee, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeApprove(grantee, UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Transfers all held tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to receive the tokens\\n */\\n function push(Token18 self, address recipient) internal {\\n push(self, recipient, balanceOf(self, address(this)));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function push(Token18 self, address recipient, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeTransfer(recipient, UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param amount Amount of tokens to transfer\\n */\\n function pull(Token18 self, address benefactor, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, address(this), UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function pullTo(Token18 self, address benefactor, address recipient, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, recipient, UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Returns the name of the token\\n * @param self Token to check for\\n * @return Token name\\n */\\n function name(Token18 self) internal view returns (string memory) {\\n return IERC20Metadata(Token18.unwrap(self)).name();\\n }\\n\\n /**\\n * @notice Returns the symbol of the token\\n * @param self Token to check for\\n * @return Token symbol\\n */\\n function symbol(Token18 self) internal view returns (string memory) {\\n return IERC20Metadata(Token18.unwrap(self)).symbol();\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of the caller\\n * @param self Token to check for\\n * @return Token balance of the caller\\n */\\n function balanceOf(Token18 self) internal view returns (UFixed18) {\\n return balanceOf(self, address(this));\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of `account`\\n * @param self Token to check for\\n * @param account Account to check\\n * @return Token balance of the account\\n */\\n function balanceOf(Token18 self, address account) internal view returns (UFixed18) {\\n return UFixed18.wrap(IERC20(Token18.unwrap(self)).balanceOf(account));\\n }\\n}\\n\\nlibrary Token18StorageLib {\\n function read(Token18Storage self) internal view returns (Token18 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(Token18Storage self, Token18 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6b12afaece814f0ab186200a4729e93eb685a21d3e9b5a3372ff283a7ad5dc23\",\"license\":\"Apache-2.0\"},\"@equilibria/root/token/types/Token6.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"../../number/types/UFixed18.sol\\\";\\n\\n/// @dev Token6\\ntype Token6 is address;\\nusing Token6Lib for Token6 global;\\ntype Token6Storage is bytes32;\\nusing Token6StorageLib for Token6Storage global;\\n\\n/**\\n * @title Token6Lib\\n * @notice Library to manage 6-decimal ERC20s that is compliant with the fixed-decimal types.\\n * @dev Automatically converts from Base-6 token amounts to Base-18 UFixed18 amounts, with optional rounding\\n */\\nlibrary Token6Lib {\\n using SafeERC20 for IERC20;\\n\\n Token6 public constant ZERO = Token6.wrap(address(0));\\n\\n uint256 private constant OFFSET = 1e12;\\n\\n /**\\n * @notice Returns whether a token is the zero address\\n * @param self Token to check for\\n * @return Whether the token is the zero address\\n */\\n function isZero(Token6 self) internal pure returns (bool) {\\n return Token6.unwrap(self) == Token6.unwrap(ZERO);\\n }\\n\\n /**\\n * @notice Returns whether the two tokens are equal\\n * @param a First token to compare\\n * @param b Second token to compare\\n * @return Whether the two tokens are equal\\n */\\n function eq(Token6 a, Token6 b) internal pure returns (bool) {\\n return Token6.unwrap(a) == Token6.unwrap(b);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend infinite tokens from the caller\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n */\\n function approve(Token6 self, address grantee) internal {\\n IERC20(Token6.unwrap(self)).safeApprove(grantee, type(uint256).max);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend `amount` tokens from the caller\\n * @dev There are important race conditions to be aware of when using this function\\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n * @param amount Amount of tokens to approve to spend\\n */\\n function approve(Token6 self, address grantee, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend `amount` tokens from the caller\\n * @dev There are important race conditions to be aware of when using this function\\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n * @param amount Amount of tokens to approve to spend\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function approve(Token6 self, address grantee, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Transfers all held tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to receive the tokens\\n */\\n function push(Token6 self, address recipient) internal {\\n push(self, recipient, balanceOf(self, address(this)));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function push(Token6 self, address recipient, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function push(Token6 self, address recipient, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param amount Amount of tokens to transfer\\n */\\n function pull(Token6 self, address benefactor, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param amount Amount of tokens to transfer\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function pull(Token6 self, address benefactor, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Returns the name of the token\\n * @param self Token to check for\\n * @return Token name\\n */\\n function name(Token6 self) internal view returns (string memory) {\\n return IERC20Metadata(Token6.unwrap(self)).name();\\n }\\n\\n /**\\n * @notice Returns the symbol of the token\\n * @param self Token to check for\\n * @return Token symbol\\n */\\n function symbol(Token6 self) internal view returns (string memory) {\\n return IERC20Metadata(Token6.unwrap(self)).symbol();\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of the caller\\n * @param self Token to check for\\n * @return Token balance of the caller\\n */\\n function balanceOf(Token6 self) internal view returns (UFixed18) {\\n return balanceOf(self, address(this));\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of `account`\\n * @param self Token to check for\\n * @param account Account to check\\n * @return Token balance of the account\\n */\\n function balanceOf(Token6 self, address account) internal view returns (UFixed18) {\\n return fromTokenAmount(IERC20(Token6.unwrap(self)).balanceOf(account));\\n }\\n\\n /**\\n * @notice Converts the unsigned fixed-decimal amount into the token amount according to\\n * it's defined decimals\\n * @dev Provides the ability to \\\"round up\\\" the token amount which is useful in situations where\\n * are swapping one token for another and don't want to give away \\\"free\\\" units due to rounding\\n * errors in the favor of the user.\\n * @param amount Amount to convert\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n * @return Normalized token amount\\n */\\n function toTokenAmount(UFixed18 amount, bool roundUp) private pure returns (uint256) {\\n return roundUp ? Math.ceilDiv(UFixed18.unwrap(amount), OFFSET) : UFixed18.unwrap(amount) / OFFSET;\\n }\\n\\n /**\\n * @notice Converts the token amount into the unsigned fixed-decimal amount according to\\n * it's defined decimals\\n * @param amount Token amount to convert\\n * @return Normalized unsigned fixed-decimal amount\\n */\\n function fromTokenAmount(uint256 amount) private pure returns (UFixed18) {\\n return UFixed18.wrap(amount * OFFSET);\\n }\\n}\\n\\nlibrary Token6StorageLib {\\n function read(Token6Storage self) internal view returns (Token6 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(Token6Storage self, Token6 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5ec7bee45a0e13f91ab2399472cf11136496073ad470cd70244855e12a7b6e65\",\"license\":\"Apache-2.0\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0xc995bddbca1ae19788db9f8b61e63385edd3fddf89693b612d5abd1a275974d2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\"},\"contracts/interfaces/ICollateral.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"./IController.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface ICollateral {\\n event Deposit(address indexed user, IProduct indexed product, UFixed18 amount);\\n event Withdrawal(address indexed user, IProduct indexed product, UFixed18 amount);\\n event AccountSettle(IProduct indexed product, address indexed account, Fixed18 amount, UFixed18 newShortfall);\\n event ProductSettle(IProduct indexed product, UFixed18 protocolFee, UFixed18 productFee);\\n event Liquidation(address indexed user, IProduct indexed product, address liquidator, UFixed18 fee);\\n event ShortfallResolution(IProduct indexed product, UFixed18 amount);\\n event FeeClaim(address indexed account, UFixed18 amount);\\n\\n error CollateralCantLiquidate(UFixed18 totalMaintenance, UFixed18 totalCollateral);\\n error CollateralInsufficientCollateralError();\\n error CollateralUnderLimitError();\\n error CollateralZeroAddressError();\\n error CollateralAccountLiquidatingError(address account);\\n\\n function token() external view returns (Token18);\\n function fees(address account) external view returns (UFixed18);\\n function initialize(IController controller_) external;\\n function depositTo(address account, IProduct product, UFixed18 amount) external;\\n function withdrawTo(address receiver, IProduct product, UFixed18 amount) external;\\n function withdrawFrom(address account, address receiver, IProduct product, UFixed18 amount) external;\\n function liquidate(address account, IProduct product) external;\\n function settleAccount(address account, Fixed18 amount) external;\\n function settleProduct(UFixed18 amount) external;\\n function collateral(address account, IProduct product) external view returns (UFixed18);\\n function collateral(IProduct product) external view returns (UFixed18);\\n function shortfall(IProduct product) external view returns (UFixed18);\\n function liquidatable(address account, IProduct product) external view returns (bool);\\n function liquidatableNext(address account, IProduct product) external view returns (bool);\\n function resolveShortfall(IProduct product, UFixed18 amount) external;\\n function claimFee() external;\\n}\\n\",\"keccak256\":\"0x6fb67eb5fc3ed4a74522677da3349d75105389369892756a60fcab4c901d352b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IContractPayoffProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\n\\ninterface IContractPayoffProvider {\\n function payoff(Fixed18 price) external view returns (Fixed18 payoff);\\n}\\n\",\"keccak256\":\"0xd73df106d032e976fd959ee6713240e36f54277ce5f215eaec8d5a2c6720a86b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IController.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IIncentivizer.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\nimport \\\"./IMultiInvoker.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\n\\ninterface IController {\\n /// @dev Coordinator of a one or many products\\n struct Coordinator {\\n /// @dev Pending owner of the product, can accept ownership\\n address pendingOwner;\\n\\n /// @dev Owner of the product, allowed to update select parameters\\n address owner;\\n\\n /// @dev Treasury of the product, collects fees\\n address treasury;\\n }\\n\\n event CollateralUpdated(ICollateral newCollateral);\\n event IncentivizerUpdated(IIncentivizer newIncentivizer);\\n event ProductBeaconUpdated(IBeacon newProductBeacon);\\n event MultiInvokerUpdated(IMultiInvoker newMultiInvoker);\\n event ProtocolFeeUpdated(UFixed18 newProtocolFee);\\n event MinFundingFeeUpdated(UFixed18 newMinFundingFee);\\n event LiquidationFeeUpdated(UFixed18 newLiquidationFee);\\n event IncentivizationFeeUpdated(UFixed18 newIncentivizationFee);\\n event MinCollateralUpdated(UFixed18 newMinCollateral);\\n event ProgramsPerProductUpdated(uint256 newProgramsPerProduct);\\n event PauserUpdated(address newPauser);\\n event PausedUpdated(bool newPaused);\\n event CoordinatorPendingOwnerUpdated(uint256 indexed coordinatorId, address newPendingOwner);\\n event CoordinatorOwnerUpdated(uint256 indexed coordinatorId, address newOwner);\\n event CoordinatorTreasuryUpdated(uint256 indexed coordinatorId, address newTreasury);\\n event CoordinatorCreated(uint256 indexed coordinatorId, address owner);\\n event ProductCreated(IProduct indexed product, IProduct.ProductInfo productInfo);\\n\\n error ControllerNoZeroCoordinatorError();\\n error ControllerNotPauserError();\\n error ControllerNotOwnerError(uint256 controllerId);\\n error ControllerNotPendingOwnerError(uint256 controllerId);\\n error ControllerInvalidProtocolFeeError();\\n error ControllerInvalidMinFundingFeeError();\\n error ControllerInvalidLiquidationFeeError();\\n error ControllerInvalidIncentivizationFeeError();\\n error ControllerNotContractAddressError();\\n\\n function collateral() external view returns (ICollateral);\\n function incentivizer() external view returns (IIncentivizer);\\n function productBeacon() external view returns (IBeacon);\\n function multiInvoker() external view returns (IMultiInvoker);\\n function coordinators(uint256 collateralId) external view returns (Coordinator memory);\\n function coordinatorFor(IProduct product) external view returns (uint256);\\n function protocolFee() external view returns (UFixed18);\\n function minFundingFee() external view returns (UFixed18);\\n function liquidationFee() external view returns (UFixed18);\\n function incentivizationFee() external view returns (UFixed18);\\n function minCollateral() external view returns (UFixed18);\\n function programsPerProduct() external view returns (uint256);\\n function pauser() external view returns (address);\\n function paused() external view returns (bool);\\n function initialize(ICollateral collateral_, IIncentivizer incentivizer_, IBeacon productBeacon_) external;\\n function createCoordinator() external returns (uint256);\\n function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external;\\n function acceptCoordinatorOwner(uint256 coordinatorId) external;\\n function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external;\\n function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo) external returns (IProduct);\\n function updateCollateral(ICollateral newCollateral) external;\\n function updateIncentivizer(IIncentivizer newIncentivizer) external;\\n function updateProductBeacon(IBeacon newProductBeacon) external;\\n function updateMultiInvoker(IMultiInvoker newMultiInvoker) external;\\n function updateProtocolFee(UFixed18 newProtocolFee) external;\\n function updateMinFundingFee(UFixed18 newMinFundingFee) external;\\n function updateLiquidationFee(UFixed18 newLiquidationFee) external;\\n function updateIncentivizationFee(UFixed18 newIncentivizationFee) external;\\n function updateMinCollateral(UFixed18 newMinCollateral) external;\\n function updateProgramsPerProduct(uint256 newProductsPerProduct) external;\\n function updatePauser(address newPauser) external;\\n function updatePaused(bool newPaused) external;\\n function isProduct(IProduct product) external view returns (bool);\\n function owner() external view returns (address);\\n function owner(uint256 coordinatorId) external view returns (address);\\n function owner(IProduct product) external view returns (address);\\n function treasury() external view returns (address);\\n function treasury(uint256 coordinatorId) external view returns (address);\\n function treasury(IProduct product) external view returns (address);\\n}\\n\",\"keccak256\":\"0xb6798b45b76edb91f6e56380eeeacdcfb37bbeb620a2d9c3e9993c39675bbd48\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IIncentivizer.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./types/ProgramInfo.sol\\\";\\nimport \\\"./IController.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IIncentivizer {\\n event ProgramCreated(IProduct indexed product, uint256 indexed programId, ProgramInfo programInfo, UFixed18 programFeeAmount);\\n event ProgramStarted(IProduct indexed product, uint256 indexed programId, uint256 version);\\n event ProgramComplete(IProduct indexed product, uint256 indexed programId, uint256 version);\\n event Claim(IProduct indexed product, address indexed account, uint256 indexed programId, UFixed18 amount);\\n event FeeClaim(Token18 indexed token, UFixed18 amount);\\n\\n error IncentivizerNotAllowedError(IProduct product);\\n error IncentivizerTooManyProgramsError();\\n error IncentivizerNotProgramOwnerError(IProduct product, uint256 programId);\\n error IncentivizerInvalidProgramError(IProduct product, uint256 programId);\\n error IncentivizerBatchClaimArgumentMismatchError();\\n\\n function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory);\\n function fees(Token18 token) external view returns (UFixed18);\\n function initialize(IController controller_) external;\\n function create(IProduct product, ProgramInfo calldata info) external returns (uint256);\\n function complete(IProduct product, uint256 programId) external;\\n function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external;\\n function syncAccount(address account, IOracleProvider.OracleVersion memory currentOracleVersion) external;\\n function claim(IProduct product, uint256[] calldata programIds) external;\\n function claimFor(address account, IProduct product, uint256[] calldata programIds) external;\\n function claim(IProduct[] calldata products, uint256[][] calldata programIds) external;\\n function claimFee(Token18[] calldata tokens) external;\\n function active(IProduct product) external view returns (uint256);\\n function count(IProduct product) external view returns (uint256);\\n function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18);\\n function available(IProduct product, uint256 programId) external view returns (UFixed18);\\n function versionStarted(IProduct product, uint256 programId) external view returns (uint256);\\n function versionComplete(IProduct product, uint256 programId) external view returns (uint256);\\n function owner(IProduct product, uint256 programId) external view returns (address);\\n function treasury(IProduct product, uint256 programId) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd9d65d1190d830c8b797829f94194db86bb712e51f404e8c3e2c9b1df5645649\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IMultiInvoker.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\\\";\\n\\nimport \\\"./IController.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IMultiInvoker {\\n /// @dev Core protocol actions that can be composed\\n enum PerennialAction {\\n NO_OP,\\n DEPOSIT,\\n WITHDRAW,\\n OPEN_TAKE,\\n CLOSE_TAKE,\\n OPEN_MAKE,\\n CLOSE_MAKE,\\n CLAIM,\\n WRAP,\\n UNWRAP,\\n WRAP_AND_DEPOSIT,\\n WITHDRAW_AND_UNWRAP\\n }\\n\\n /// @dev Struct for action invocation\\n struct Invocation {\\n PerennialAction action;\\n bytes args;\\n }\\n\\n function initialize() external;\\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\\n function batcher() external view returns (IBatcher);\\n function controller() external view returns (IController);\\n function collateral() external view returns (ICollateral);\\n function reserve() external view returns (IEmptySetReserve);\\n function invoke(Invocation[] calldata invocations) external;\\n}\\n\",\"keccak256\":\"0x80e035472b990b026888f326b4dcceb7526491607b61e50592ceb8d36cc99728\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IParamProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\\\";\\nimport \\\"./types/PendingFeeUpdates.sol\\\";\\n\\ninterface IParamProvider {\\n event MaintenanceUpdated(UFixed18 newMaintenance, uint256 version);\\n event FundingFeeUpdated(UFixed18 newFundingFee, uint256 version);\\n event MakerFeeUpdated(UFixed18 newMakerFee, uint256 version);\\n event PendingMakerFeeUpdated(UFixed18 newMakerFee);\\n event TakerFeeUpdated(UFixed18 newTakerFee, uint256 version);\\n event PendingTakerFeeUpdated(UFixed18 newTakerFee);\\n event PositionFeeUpdated(UFixed18 newPositionFee, uint256 version);\\n event PendingPositionFeeUpdated(UFixed18 newPositionFee);\\n event MakerLimitUpdated(UFixed18 newMakerLimit, uint256 version);\\n event JumpRateUtilizationCurveUpdated(\\n JumpRateUtilizationCurve,\\n uint256 version\\n );\\n\\n error ParamProviderInvalidParamValue();\\n\\n function maintenance() external view returns (UFixed18);\\n function updateMaintenance(UFixed18 newMaintenance) external;\\n function fundingFee() external view returns (UFixed18);\\n function updateFundingFee(UFixed18 newFundingFee) external;\\n function makerFee() external view returns (UFixed18);\\n function updateMakerFee(UFixed18 newMakerFee) external;\\n function takerFee() external view returns (UFixed18);\\n function updateTakerFee(UFixed18 newTakerFee) external;\\n function positionFee() external view returns (UFixed18);\\n function updatePositionFee(UFixed18 newPositionFee) external;\\n function makerLimit() external view returns (UFixed18);\\n function updateMakerLimit(UFixed18 newMakerLimit) external;\\n function utilizationCurve() external view returns (JumpRateUtilizationCurve memory);\\n function updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) external;\\n function pendingFeeUpdates() external view returns (PendingFeeUpdates memory);\\n}\\n\",\"keccak256\":\"0x21584bd07296eb4e8bd6076fd20afad320e781c19c60b479c9340c69b0f37517\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IPayoffProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\n\\ninterface IPayoffProvider {\\n event OracleUpdated(address newOracle, uint256 oracleVersion);\\n\\n error PayoffProviderInvalidOracle();\\n error PayoffProviderInvalidPayoffDefinitionError();\\n\\n function oracle() external view returns (IOracleProvider);\\n function payoffDefinition() external view returns (PayoffDefinition memory);\\n function currentVersion() external view returns (IOracleProvider.OracleVersion memory);\\n function atVersion(uint256 oracleVersion) external view returns (IOracleProvider.OracleVersion memory);\\n}\\n\",\"keccak256\":\"0x803d22f7513c2c5186f77f6bc7cc34673ed762e40f106f9aef512eb9b57018af\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IProduct.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\\\";\\nimport \\\"./IPayoffProvider.sol\\\";\\nimport \\\"./IParamProvider.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\nimport \\\"./types/Position.sol\\\";\\nimport \\\"./types/PrePosition.sol\\\";\\nimport \\\"./types/Accumulator.sol\\\";\\n\\ninterface IProduct is IPayoffProvider, IParamProvider {\\n /// @dev Product Creation parameters\\n struct ProductInfo {\\n /// @dev name of the product\\n string name;\\n\\n /// @dev symbol of the product\\n string symbol;\\n\\n /// @dev product payoff definition\\n PayoffDefinition payoffDefinition;\\n\\n /// @dev oracle address\\n IOracleProvider oracle;\\n\\n /// @dev product maintenance ratio\\n UFixed18 maintenance;\\n\\n /// @dev product funding fee\\n UFixed18 fundingFee;\\n\\n /// @dev product maker fee\\n UFixed18 makerFee;\\n\\n /// @dev product taker fee\\n UFixed18 takerFee;\\n\\n /// @dev product position fee share\\n UFixed18 positionFee;\\n\\n /// @dev product maker limit\\n UFixed18 makerLimit;\\n\\n /// @dev utulization curve definition\\n JumpRateUtilizationCurve utilizationCurve;\\n }\\n\\n event Settle(uint256 preVersion, uint256 toVersion);\\n event AccountSettle(address indexed account, uint256 preVersion, uint256 toVersion);\\n event MakeOpened(address indexed account, uint256 version, UFixed18 amount);\\n event TakeOpened(address indexed account, uint256 version, UFixed18 amount);\\n event MakeClosed(address indexed account, uint256 version, UFixed18 amount);\\n event TakeClosed(address indexed account, uint256 version, UFixed18 amount);\\n event ClosedUpdated(bool indexed newClosed, uint256 version);\\n\\n error ProductInsufficientLiquidityError(UFixed18 socializationFactor);\\n error ProductDoubleSidedError();\\n error ProductOverClosedError();\\n error ProductInsufficientCollateralError();\\n error ProductInLiquidationError();\\n error ProductMakerOverLimitError();\\n error ProductOracleBootstrappingError();\\n error ProductClosedError();\\n\\n function name() external view returns (string memory);\\n function symbol() external view returns (string memory);\\n function initialize(ProductInfo calldata productInfo_) external;\\n function settle() external;\\n function settleAccount(address account) external;\\n function openTake(UFixed18 amount) external;\\n function openTakeFor(address account, UFixed18 amount) external;\\n function closeTake(UFixed18 amount) external;\\n function closeTakeFor(address account, UFixed18 amount) external;\\n function openMake(UFixed18 amount) external;\\n function openMakeFor(address account, UFixed18 amount) external;\\n function closeMake(UFixed18 amount) external;\\n function closeMakeFor(address account, UFixed18 amount) external;\\n function closeAll(address account) external;\\n function maintenance(address account) external view returns (UFixed18);\\n function maintenanceNext(address account) external view returns (UFixed18);\\n function isClosed(address account) external view returns (bool);\\n function isLiquidating(address account) external view returns (bool);\\n function position(address account) external view returns (Position memory);\\n function pre(address account) external view returns (PrePosition memory);\\n function latestVersion() external view returns (uint256);\\n function positionAtVersion(uint256 oracleVersion) external view returns (Position memory);\\n function pre() external view returns (PrePosition memory);\\n function valueAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\\n function shareAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\\n function latestVersion(address account) external view returns (uint256);\\n function rate(Position memory position) external view returns (Fixed18);\\n function closed() external view returns (bool);\\n function updateClosed(bool newClosed) external;\\n function updateOracle(IOracleProvider newOracle) external;\\n}\\n\",\"keccak256\":\"0x8e53ea97d8d59519adcbc2aa3600b5e51de1d59efec485a88eca8b574a35a00f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/Accumulator.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"./PackedAccumulator.sol\\\";\\n\\n/// @dev Accumulator type\\nstruct Accumulator {\\n /// @dev maker accumulator per share\\n Fixed18 maker;\\n /// @dev taker accumulator per share\\n Fixed18 taker;\\n}\\nusing AccumulatorLib for Accumulator global;\\n\\n/**\\n * @title AccountAccumulatorLib\\n * @notice Library that surfaces math operations for the Accumulator type.\\n * @dev Accumulators track the cumulative change in position value over time for the maker and taker positions\\n * respectively. Account-level accumulators can then use two of these values `a` and `a'` to compute the\\n * change in position value since last sync. This change in value is then used to compute P&L and fees.\\n */\\nlibrary AccumulatorLib {\\n /**\\n * @notice Creates a packed accumulator from an accumulator\\n * @param self an accumulator\\n * @return New packed accumulator\\n */\\n function pack(Accumulator memory self) internal pure returns (PackedAccumulator memory) {\\n return PackedAccumulator({maker: self.maker.pack(), taker: self.taker.pack()});\\n }\\n\\n /**\\n * @notice Adds two accumulators together\\n * @param a The first accumulator to sum\\n * @param b The second accumulator to sum\\n * @return The resulting summed accumulator\\n */\\n function add(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\\n }\\n\\n /**\\n * @notice Subtracts accumulator `b` from `a`\\n * @param a The accumulator to subtract from\\n * @param b The accumulator to subtract\\n * @return The resulting subtracted accumulator\\n */\\n function sub(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\\n }\\n\\n /**\\n * @notice Multiplies two accumulators together\\n * @param a The first accumulator to multiply\\n * @param b The second accumulator to multiply\\n * @return The resulting multiplied accumulator\\n */\\n function mul(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: a.maker.mul(b.maker), taker: a.taker.mul(b.taker)});\\n }\\n\\n /**\\n * @notice Sums the maker and taker together from a single accumulator\\n * @param self The struct to operate on\\n * @return The sum of its maker and taker\\n */\\n function sum(Accumulator memory self) internal pure returns (Fixed18) {\\n return self.maker.add(self.taker);\\n }\\n}\\n\",\"keccak256\":\"0x7ccd0a72aa593cefb9f4337cf312799f357b82fcb3f0379de0dc503d1cb7e387\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PackedAccumulator.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/PackedFixed18.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\n\\n/// @dev PackedAccumulator type\\nstruct PackedAccumulator {\\n /// @dev maker accumulator per share\\n PackedFixed18 maker;\\n /// @dev taker accumulator per share\\n PackedFixed18 taker;\\n}\\nusing PackedAccumulatorLib for PackedAccumulator global;\\n\\n/**\\n * @title PackedAccumulatorLib\\n * @dev A packed version of the Accumulator which takes up a single storage slot using `PackedFixed18` values.\\n * @notice Library for the packed Accumulator type.\\n */\\nlibrary PackedAccumulatorLib {\\n /**\\n * @notice Creates an accumulator from a packed accumulator\\n * @param self packed accumulator\\n * @return New accumulator\\n */\\n function unpack(PackedAccumulator memory self) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: self.maker.unpack(), taker: self.taker.unpack()});\\n }\\n}\\n\",\"keccak256\":\"0xd83f2822d4f6c818087a232b54007730992c34ff77377fc307a282f886e7cf65\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PackedPosition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/PackedUFixed18.sol\\\";\\nimport \\\"./Position.sol\\\";\\n\\n/// @dev PackedPosition type\\nstruct PackedPosition {\\n /// @dev Quantity of the maker position\\n PackedUFixed18 maker;\\n /// @dev Quantity of the taker position\\n PackedUFixed18 taker;\\n}\\nusing PackedPositionLib for PackedPosition global;\\n\\n/**\\n * @title PackedPositionLib\\n * @dev A packed version of the Position which takes up a single storage slot using `PackedFixed18` values.\\n * @notice Library for the packed Position type.\\n */\\nlibrary PackedPositionLib {\\n /**\\n * @notice Creates an position from a packed position\\n * @param self packed position\\n * @return New position\\n */\\n function unpack(PackedPosition memory self) internal pure returns (Position memory) {\\n return Position({maker: self.maker.unpack(), taker: self.taker.unpack()});\\n }\\n}\\n\",\"keccak256\":\"0x04968e6794f6244cb3415cea111d640273a81faea957872988d0cb580f45df1e\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PayoffDefinition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../../interfaces/IContractPayoffProvider.sol\\\";\\n\\n/// @dev PayoffDefinition tyoe\\nstruct PayoffDefinition {\\n PayoffDefinitionLib.PayoffType payoffType;\\n PayoffDefinitionLib.PayoffDirection payoffDirection;\\n bytes30 data;\\n}\\nusing PayoffDefinitionLib for PayoffDefinition global;\\ntype PayoffDefinitionStorage is bytes32;\\nusing PayoffDefinitionStorageLib for PayoffDefinitionStorage global;\\n\\n/**\\n * @title PayoffDefinitionLib\\n * @dev Library that surfaces logic for PayoffDefinition type functionality\\n * @notice Library for the PayoffDefinition type. Performs validity and price transformation\\n based on the payoff definition type.\\n */\\nlibrary PayoffDefinitionLib {\\n using Address for address;\\n\\n error PayoffDefinitionUnsupportedTransform(PayoffType payoffType, PayoffDirection payoffDirection);\\n error PayoffDefinitionNotContract(PayoffType payoffType, bytes30 data);\\n\\n /// @dev Payoff function type enum\\n enum PayoffType { PASSTHROUGH, CONTRACT }\\n enum PayoffDirection { LONG, SHORT }\\n\\n /**\\n * @notice Checks validity of the payoff definition\\n * @param self a payoff definition\\n * @return Whether the payoff definition is valid for it's given type\\n */\\n function valid(PayoffDefinition memory self) internal view returns (bool) {\\n if (self.payoffType == PayoffType.CONTRACT) return address(_providerContract(self)).isContract();\\n\\n // All other payoff types should have no data\\n return uint(bytes32(self.data)) == 0;\\n }\\n\\n /**\\n * @notice Transforms a price based on the payoff definition\\n * @param self a payoff definition\\n * @param price raw oracle price\\n * @return Price transformed by the payoff definition function\\n */\\n function transform(\\n PayoffDefinition memory self,\\n Fixed18 price\\n ) internal view returns (Fixed18) {\\n PayoffType payoffType = self.payoffType;\\n PayoffDirection payoffDirection = self.payoffDirection;\\n Fixed18 transformedPrice;\\n\\n // First get the price depending on the type\\n if (payoffType == PayoffType.PASSTHROUGH) transformedPrice = price;\\n else if (payoffType == PayoffType.CONTRACT) transformedPrice = _payoffFromContract(self, price);\\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\\n\\n // Then transform it depending on the direction flag\\n if (self.payoffDirection == PayoffDirection.LONG) return transformedPrice;\\n else if (self.payoffDirection == PayoffDirection.SHORT) return transformedPrice.mul(Fixed18Lib.NEG_ONE);\\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\\n }\\n\\n /**\\n * @notice Parses the data field into an address\\n * @dev Reverts if payoffType is not CONTRACT\\n * @param self a payoff definition\\n * @return IContractPayoffProvider address\\n */\\n function _providerContract(\\n PayoffDefinition memory self\\n ) private pure returns (IContractPayoffProvider) {\\n if (self.payoffType != PayoffType.CONTRACT) revert PayoffDefinitionNotContract(self.payoffType, self.data);\\n // Shift to pull the last 20 bytes, then cast to an address\\n return IContractPayoffProvider(address(bytes20(self.data << 80)));\\n }\\n\\n /**\\n * @notice Performs a price transformation by calling the underlying payoff contract\\n * @param self a payoff definition\\n * @param price raw oracle price\\n * @return Price transformed by the payoff definition function on the contract\\n */\\n function _payoffFromContract(\\n PayoffDefinition memory self,\\n Fixed18 price\\n ) private view returns (Fixed18) {\\n bytes memory ret = address(_providerContract(self)).functionStaticCall(\\n abi.encodeCall(IContractPayoffProvider.payoff, price)\\n );\\n return Fixed18.wrap(abi.decode(ret, (int256)));\\n }\\n}\\n\\n/**\\n * @title PayoffDefinitionStorageLib\\n * @notice Library that surfaces storage read and writes for the PayoffDefinition type\\n */\\nlibrary PayoffDefinitionStorageLib {\\n function read(PayoffDefinitionStorage self) internal view returns (PayoffDefinition memory) {\\n return _storagePointer(self);\\n }\\n\\n function store(PayoffDefinitionStorage self, PayoffDefinition memory value) internal {\\n PayoffDefinition storage storagePointer = _storagePointer(self);\\n\\n storagePointer.payoffType = value.payoffType;\\n storagePointer.payoffDirection = value.payoffDirection;\\n storagePointer.data = value.data;\\n }\\n\\n function _storagePointer(\\n PayoffDefinitionStorage self\\n ) private pure returns (PayoffDefinition storage pointer) {\\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\\n }\\n}\\n\",\"keccak256\":\"0x99f9b5d5facba16885a375beac2a05129e7b23a8cceee048a7affd7f12a18a8f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PendingFeeUpdates.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\n/// @dev PendingFeeUpdates type. Fees can be between 0 and 1 ** 10^18, so uint64 is sufficient\\nstruct PendingFeeUpdates {\\n bool makerFeeUpdated;\\n uint64 pendingMakerFee;\\n bool takerFeeUpdated;\\n uint64 pendingTakerFee;\\n bool positionFeeUpdated;\\n uint64 pendingPositionFee;\\n}\\nusing PendingFeeUpdatesLib for PendingFeeUpdates global;\\ntype PendingFeeUpdatesStorage is bytes32;\\nusing PendingFeeUpdatesStorageLib for PendingFeeUpdatesStorage global;\\n\\n/**\\n * @title PendingFeeUpdatesLib\\n * @dev Library that surfaces convenience functions for the PendingFeeUpdates type\\n * @notice Library for the PendingFeeUpdates type. Allows for setting and reading fee updates and clearing state\\n */\\nlibrary PendingFeeUpdatesLib {\\n error PendingFeeUpdatesUnsupportedValue(UFixed18 value);\\n\\n /**\\n * @notice Updates the pending maker fee to `newMakerFee` and sets the `makerFeeUpdated` flag\\n * @dev Reverts if `newMakerFee` is invalid\\n * @param self PendingFeeUpdates struct\\n * @param newMakerFee new maker fee value\\n */\\n function updateMakerFee(PendingFeeUpdates memory self, UFixed18 newMakerFee) internal pure {\\n if (UFixed18.unwrap(newMakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newMakerFee);\\n self.pendingMakerFee = uint64(UFixed18.unwrap(newMakerFee));\\n self.makerFeeUpdated = true;\\n }\\n\\n /// @dev Returns the UFixed18-wrapped pending maker fee\\n function makerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(self.pendingMakerFee));\\n }\\n\\n /**\\n * @notice Updates the pending taker fee to `newTakerFee` and sets the `takerFeeUpdated` flag\\n * @dev Reverts if `newTakerFee` is invalid\\n * @param self PendingFeeUpdates struct\\n * @param newTakerFee new taker fee value\\n */\\n function updateTakerFee(PendingFeeUpdates memory self, UFixed18 newTakerFee) internal pure {\\n if (UFixed18.unwrap(newTakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newTakerFee);\\n self.pendingTakerFee = uint64(UFixed18.unwrap(newTakerFee));\\n self.takerFeeUpdated = true;\\n }\\n\\n /// @dev Returns the UFixed18-wrapped pending taker fee\\n function takerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(self.pendingTakerFee));\\n }\\n\\n /**\\n * @notice Updates the pending position fee to `newPositionFee` and sets the `positionFeeUpdated` flag\\n * @dev Reverts if `newPositionFee` is invalid\\n * @param self PendingFeeUpdates struct\\n * @param newPositionFee new position fee value\\n */\\n function updatePositionFee(PendingFeeUpdates memory self, UFixed18 newPositionFee) internal pure {\\n if (UFixed18.unwrap(newPositionFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newPositionFee);\\n self.pendingPositionFee = uint64(UFixed18.unwrap(newPositionFee));\\n self.positionFeeUpdated = true;\\n }\\n\\n /// @dev Returns the UFixed18-wrapped pending position fee\\n function positionFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(self.pendingPositionFee));\\n }\\n\\n /// @dev Returns true if any of the updated flags are true\\n function hasUpdates(PendingFeeUpdates memory self) internal pure returns (bool) {\\n return self.makerFeeUpdated || self.takerFeeUpdated || self.positionFeeUpdated;\\n }\\n\\n /// @dev Resets all struct values to defaults\\n function clear(PendingFeeUpdates memory self) internal pure {\\n self.makerFeeUpdated = false;\\n self.pendingMakerFee = 0;\\n self.takerFeeUpdated = false;\\n self.pendingTakerFee = 0;\\n self.positionFeeUpdated = false;\\n self.pendingPositionFee = 0;\\n }\\n}\\n\\n/**\\n * @title PendingFeeUpdatesStorageLib\\n * @notice Library that surfaces storage read and writes for the PendingFeeUpdates type\\n */\\nlibrary PendingFeeUpdatesStorageLib {\\n struct PendingFeeUpdatesStoragePointer {\\n PendingFeeUpdates value;\\n }\\n\\n function read(PendingFeeUpdatesStorage self) internal view returns (PendingFeeUpdates memory) {\\n return _storagePointer(self).value;\\n }\\n\\n function store(PendingFeeUpdatesStorage self, PendingFeeUpdates memory value) internal {\\n _storagePointer(self).value = value;\\n }\\n\\n function _storagePointer(\\n PendingFeeUpdatesStorage self\\n ) private pure returns (PendingFeeUpdatesStoragePointer storage pointer) {\\n /// @solidity memory-safe-assembly\\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\\n }\\n}\\n\",\"keccak256\":\"0xd98c681bdd6e1808e311615b3c4ac3b557ce5ec461f7b1cc645a51590eaf6f93\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/Position.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\nimport \\\"./PrePosition.sol\\\";\\nimport \\\"./PackedPosition.sol\\\";\\n\\n/// @dev Position type\\nstruct Position {\\n /// @dev Quantity of the maker position\\n UFixed18 maker;\\n /// @dev Quantity of the taker position\\n UFixed18 taker;\\n}\\nusing PositionLib for Position global;\\n\\n/**\\n * @title PositionLib\\n * @notice Library that surfaces math and settlement computations for the Position type.\\n * @dev Positions track the current quantity of the account's maker and taker positions respectively\\n * denominated as a unit of the product's payoff function.\\n */\\nlibrary PositionLib {\\n /**\\n * @notice Creates a packed position from an position\\n * @param self A position\\n * @return New packed position\\n */\\n function pack(Position memory self) internal pure returns (PackedPosition memory) {\\n return PackedPosition({maker: self.maker.pack(), taker: self.taker.pack()});\\n }\\n\\n /**\\n * @notice Returns whether the position is fully empty\\n * @param self A position\\n * @return Whether the position is empty\\n */\\n function isEmpty(Position memory self) internal pure returns (bool) {\\n return self.maker.isZero() && self.taker.isZero();\\n }\\n\\n /**\\n * @notice Adds position `a` and `b` together, returning the result\\n * @param a The first position to sum\\n * @param b The second position to sum\\n * @return Resulting summed position\\n */\\n function add(Position memory a, Position memory b) internal pure returns (Position memory) {\\n return Position({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\\n }\\n\\n /**\\n * @notice Subtracts position `b` from `a`, returning the result\\n * @param a The position to subtract from\\n * @param b The position to subtract\\n * @return Resulting subtracted position\\n */\\n function sub(Position memory a, Position memory b) internal pure returns (Position memory) {\\n return Position({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\\n }\\n\\n /**\\n * @notice Multiplies position `self` by accumulator `accumulator` and returns the resulting accumulator\\n * @param self The Position to operate on\\n * @param accumulator The accumulator to multiply by\\n * @return Resulting multiplied accumulator\\n */\\n function mul(Position memory self, Accumulator memory accumulator) internal pure returns (Accumulator memory) {\\n return Accumulator({\\n maker: Fixed18Lib.from(self.maker).mul(accumulator.maker),\\n taker: Fixed18Lib.from(self.taker).mul(accumulator.taker)\\n });\\n }\\n\\n /**\\n * @notice Scales position `self` by fixed-decimal `scale` and returns the resulting position\\n * @param self The Position to operate on\\n * @param scale The Fixed-decimal to scale by\\n * @return Resulting scaled position\\n */\\n function mul(Position memory self, UFixed18 scale) internal pure returns (Position memory) {\\n return Position({maker: self.maker.mul(scale), taker: self.taker.mul(scale)});\\n }\\n\\n /**\\n * @notice Divides position `self` by `b` and returns the resulting accumulator\\n * @param self The Position to operate on\\n * @param b The number to divide by\\n * @return Resulting divided accumulator\\n */\\n function div(Position memory self, uint256 b) internal pure returns (Accumulator memory) {\\n return Accumulator({\\n maker: Fixed18Lib.from(self.maker).div(Fixed18Lib.from(UFixed18Lib.from(b))),\\n taker: Fixed18Lib.from(self.taker).div(Fixed18Lib.from(UFixed18Lib.from(b)))\\n });\\n }\\n\\n /**\\n * @notice Returns the maximum of `self`'s maker and taker values\\n * @param self The struct to operate on\\n * @return Resulting maximum value\\n */\\n function max(Position memory self) internal pure returns (UFixed18) {\\n return UFixed18Lib.max(self.maker, self.taker);\\n }\\n\\n /**\\n * @notice Sums the maker and taker together from a single position\\n * @param self The struct to operate on\\n * @return The sum of its maker and taker\\n */\\n function sum(Position memory self) internal pure returns (UFixed18) {\\n return self.maker.add(self.taker);\\n }\\n\\n /**\\n * @notice Computes the next position after the pending-settlement position delta is included\\n * @param self The current Position\\n * @param pre The pending-settlement position delta\\n * @return Next Position\\n */\\n function next(Position memory self, PrePosition memory pre) internal pure returns (Position memory) {\\n return sub(add(self, pre.openPosition), pre.closePosition);\\n }\\n\\n /**\\n * @notice Returns the settled position at oracle version `toOracleVersion`\\n * @dev Checks if a new position is ready to be settled based on the provided `toOracleVersion`\\n * and `pre` and returns accordingly\\n * @param self The current Position\\n * @param pre The pending-settlement position delta\\n * @param toOracleVersion The oracle version to settle to\\n * @return Settled position at oracle version\\n * @return Whether a new position was settled\\n */\\n function settled(\\n Position memory self,\\n PrePosition memory pre,\\n IOracleProvider.OracleVersion memory toOracleVersion\\n ) internal pure returns (Position memory, bool) {\\n return pre.canSettle(toOracleVersion) ? (next(self, pre), true) : (self, false);\\n }\\n\\n /**\\n * @notice Returns the socialization factor for the current position\\n * @dev Socialization account for the case where `taker` > `maker` temporarily due to a liquidation\\n * on the maker side. This dampens the taker's exposure pro-rata to ensure that the maker side\\n * is never exposed over 1 x short.\\n * @param self The Position to operate on\\n * @return Socialization factor\\n */\\n function socializationFactor(Position memory self) internal pure returns (UFixed18) {\\n return self.taker.isZero() ? UFixed18Lib.ONE : UFixed18Lib.min(UFixed18Lib.ONE, self.maker.div(self.taker));\\n }\\n}\\n\",\"keccak256\":\"0x367918730021f3d6b7035f40c53b00b4316eb5e7fa409ed6285ba6d49971aab1\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PrePosition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\n\\n/// @dev PrePosition type\\nstruct PrePosition {\\n /// @dev Oracle version at which the new position delta was recorded\\n uint256 oracleVersion;\\n\\n /// @dev Size of position to open at oracle version\\n Position openPosition;\\n\\n /// @dev Size of position to close at oracle version\\n Position closePosition;\\n}\\nusing PrePositionLib for PrePosition global;\\n\\n/**\\n * @title PrePositionLib\\n * @notice Library that manages a pre-settlement position delta.\\n * @dev PrePositions track the currently awaiting-settlement deltas to a settled Position. These are\\n * Primarily necessary to introduce lag into the settlement system such that oracle lag cannot be\\n * gamed to a user's advantage. When a user opens or closes a new position, it sits as a PrePosition\\n * for one oracle version until it's settle into the Position, making it then effective. PrePositions\\n * are automatically settled at the correct oracle version even if a flywheel call doesn't happen until\\n * several version into the future by using the historical version lookups in the corresponding \\\"Versioned\\\"\\n * global state types.\\n */\\nlibrary PrePositionLib {\\n /**\\n * @notice Returns whether there is no pending-settlement position delta\\n * @param self The struct to operate on\\n * @return Whether the pending-settlement position delta is empty\\n */\\n function isEmpty(PrePosition memory self) internal pure returns (bool) {\\n return self.openPosition.isEmpty() && self.closePosition.isEmpty();\\n }\\n\\n /**\\n * @notice Increments the maker side of the open position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The position amount to open\\n */\\n function openMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.openPosition.maker = self.openPosition.maker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Increments the maker side of the close position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The maker position amount to close\\n */\\n function closeMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.closePosition.maker = self.closePosition.maker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Increments the taker side of the open position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The taker position amount to open\\n */\\n function openTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.openPosition.taker = self.openPosition.taker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Increments the taker side of the close position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The taker position amount to close\\n */\\n function closeTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.closePosition.taker = self.closePosition.taker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Returns whether the the pending position delta can be settled at version `toOracleVersion`\\n * @dev Pending-settlement positions deltas can be settled (1) oracle version after they are recorded\\n * @param self The struct to operate on\\n * @param toOracleVersion The potential oracle version to settle\\n * @return Whether the position delta can be settled\\n */\\n function canSettle(\\n PrePosition memory self,\\n IOracleProvider.OracleVersion memory toOracleVersion\\n ) internal pure returns (bool) {\\n return !isEmpty(self) && toOracleVersion.version > self.oracleVersion;\\n }\\n\\n /**\\n * @notice Computes the fee incurred for opening or closing the pending-settlement position\\n * @dev Must be called from a valid product to get the proper fee amounts\\n * @param self The struct to operate on\\n * @param latestOracleVersion The oracle version at which position was modified\\n * @return The maker / taker fee incurred\\n */\\n function computeFee(\\n PrePosition memory self,\\n IOracleProvider.OracleVersion memory latestOracleVersion\\n ) internal view returns (Position memory) {\\n Position memory positionDelta = self.openPosition.add(self.closePosition);\\n\\n (UFixed18 makerNotional, UFixed18 takerNotional) = (\\n Fixed18Lib.from(positionDelta.maker).mul(latestOracleVersion.price).abs(),\\n Fixed18Lib.from(positionDelta.taker).mul(latestOracleVersion.price).abs()\\n );\\n\\n IProduct product = IProduct(address(this));\\n return Position(makerNotional.mul(product.makerFee()), takerNotional.mul(product.takerFee()));\\n }\\n\\n /**\\n * @notice Computes the next oracle version to settle\\n * @dev - If there is no pending-settlement position delta, returns the current oracle version\\n * - Otherwise returns the oracle version at which the pending-settlement position delta can be first settled\\n *\\n * Corresponds to point (b) in the Position settlement flow\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @return Next oracle version to settle\\n */\\n function settleVersion(PrePosition storage self, uint256 currentVersion) internal view returns (uint256) {\\n uint256 _oracleVersion = self.oracleVersion;\\n return _oracleVersion == 0 ? currentVersion : _oracleVersion + 1;\\n }\\n}\\n\",\"keccak256\":\"0x4d4443c34648f0352ed7c26ce8b837b6c7613169e53e95d92c8c59ee9e335692\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/ProgramInfo.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\n\\n/// @dev ProgramInfo type\\nstruct ProgramInfo {\\n /// @dev Coordinator for this program\\n uint256 coordinatorId;\\n\\n /// @dev Amount of total maker and taker rewards\\n Position amount;\\n\\n /// @dev start timestamp of the program\\n uint256 start;\\n\\n /// @dev duration of the program (in seconds)\\n uint256 duration;\\n\\n /**\\n * @dev Reward ERC20 token contract\\n * @notice Perennial does not support non-standard ERC20s as reward tokens for incentive programs, including,\\n but not limited to: fee on transfer and rebase tokens. Using such a non-standard token will likely\\n result in loss of funds.\\n */\\n Token18 token;\\n}\\nusing ProgramInfoLib for ProgramInfo global;\\n\\n/**\\n * @title ProgramInfoLib\\n * @notice Library that snapshots the static information for a single program.\\n * @dev This information does not change during the operation of a program.\\n */\\nlibrary ProgramInfoLib {\\n uint256 private constant MIN_DURATION = 1 days;\\n uint256 private constant MAX_DURATION = 2 * 365 days;\\n\\n error ProgramInvalidStartError();\\n error ProgramInvalidDurationError();\\n\\n /**\\n * @notice Validates and creates a new Program\\n * @dev Reverts for invalid programInfos\\n * @param programInfo Un-sanitized static program information\\n */\\n function validate(ProgramInfo memory programInfo) internal view {\\n if (isStarted(programInfo, block.timestamp)) revert ProgramInvalidStartError();\\n if (programInfo.duration < MIN_DURATION || programInfo.duration > MAX_DURATION) revert ProgramInvalidDurationError();\\n }\\n\\n /**\\n * @notice Computes a new program info with the fee taken out of the amount\\n * @param programInfo Original program info\\n * @param incentivizationFee The incentivization fee\\n * @return New program info\\n * @return Fee amount\\n */\\n function deductFee(ProgramInfo memory programInfo, UFixed18 incentivizationFee)\\n internal pure returns (ProgramInfo memory, UFixed18) {\\n Position memory newProgramAmount = programInfo.amount.mul(UFixed18Lib.ONE.sub(incentivizationFee));\\n UFixed18 programFeeAmount = programInfo.amount.sub(newProgramAmount).sum();\\n programInfo.amount = newProgramAmount;\\n return (programInfo, programFeeAmount);\\n }\\n\\n /**\\n * @notice Returns the maker and taker amounts per position share\\n * @param self The ProgramInfo to operate on\\n * @return programFee Amounts per share\\n */\\n function amountPerShare(ProgramInfo memory self) internal pure returns (Accumulator memory) {\\n return self.amount.div(self.duration);\\n }\\n\\n /**\\n * @notice Returns whether the program has started by timestamp `timestamp`\\n * @param self The ProgramInfo to operate on\\n * @param timestamp Timestamp to check for\\n * @return Whether the program has started\\n */\\n function isStarted(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\\n return timestamp >= self.start;\\n }\\n\\n /**\\n * @notice Returns whether the program is completed by timestamp `timestamp`\\n * @param self The ProgramInfo to operate on\\n * @param timestamp Timestamp to check for\\n * @return Whether the program is completed\\n */\\n function isComplete(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\\n return timestamp >= (self.start + self.duration);\\n }\\n}\\n\",\"keccak256\":\"0x280fcaf931b49abaec46b95ccbabaaf856a4b8e8d036413c9c3b3af25585d161\",\"license\":\"Apache-2.0\"},\"contracts/multiinvoker/MultiInvoker.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.15;\\n\\nimport \\\"@equilibria/root/control/unstructured/UInitializable.sol\\\";\\n\\nimport \\\"../interfaces/IMultiInvoker.sol\\\";\\n\\ncontract MultiInvoker is IMultiInvoker, UInitializable {\\n /// @dev USDC stablecoin address\\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\\n\\n /// @dev DSU address\\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\\n\\n /// @dev Batcher address\\n IBatcher public immutable batcher;\\n\\n /// @dev Controller address\\n IController public immutable controller;\\n\\n /// @dev Collateral address\\n ICollateral public immutable collateral;\\n\\n /// @dev Reserve address\\n IEmptySetReserve public immutable reserve;\\n\\n /**\\n * @notice Initializes the immutable contract state\\n * @dev Called at implementation instantiate and constant for that implementation.\\n * @param usdc_ USDC stablecoin address\\n * @param batcher_ Protocol Batcher address\\n * @param reserve_ EmptySet Reserve address\\n * @param controller_ Protocol Controller address\\n */\\n constructor(Token6 usdc_, IBatcher batcher_, IEmptySetReserve reserve_, IController controller_) {\\n USDC = usdc_;\\n batcher = batcher_;\\n controller = controller_;\\n collateral = controller.collateral();\\n DSU = collateral.token();\\n reserve = reserve_;\\n }\\n\\n /**\\n * @notice Initializes the contract state\\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\\n * avoid front-running\\n */\\n function initialize() external initializer(2) {\\n if (address(batcher) != address(0)) {\\n DSU.approve(address(batcher), UFixed18Lib.ZERO);\\n DSU.approve(address(batcher));\\n USDC.approve(address(batcher), UFixed18Lib.ZERO);\\n USDC.approve(address(batcher));\\n }\\n\\n DSU.approve(address(collateral), UFixed18Lib.ZERO);\\n DSU.approve(address(collateral));\\n\\n DSU.approve(address(reserve), UFixed18Lib.ZERO);\\n DSU.approve(address(reserve));\\n USDC.approve(address(reserve), UFixed18Lib.ZERO);\\n USDC.approve(address(reserve));\\n }\\n\\n /**\\n * @notice Executes a list of invocations in order\\n * @param invocations The list of invocations to execute in order\\n */\\n function invoke(Invocation[] calldata invocations) external {\\n for (uint256 i = 0; i < invocations.length; i++) {\\n Invocation memory invocation = invocations[i];\\n\\n // Deposit from `msg.sender` into `account`s `product` collateral account\\n if (invocation.action == PerennialAction.DEPOSIT) {\\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n depositTo(account, product, amount);\\n\\n // Withdraw from `msg.sender`s `product` collateral account to `receiver`\\n } else if (invocation.action == PerennialAction.WITHDRAW) {\\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n collateral.withdrawFrom(msg.sender, receiver, product, amount);\\n\\n // Open a take position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.OPEN_TAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n product.openTakeFor(msg.sender, amount);\\n\\n // Close a take position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.CLOSE_TAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n product.closeTakeFor(msg.sender, amount);\\n\\n // Open a make position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.OPEN_MAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n product.openMakeFor(msg.sender, amount);\\n\\n // Close a make position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.CLOSE_MAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n product.closeMakeFor(msg.sender, amount);\\n\\n // Claim `msg.sender`s incentive reward for `product` programs\\n } else if (invocation.action == PerennialAction.CLAIM) {\\n (IProduct product, uint256[] memory programIds) = abi.decode(invocation.args, (IProduct, uint256[]));\\n controller.incentivizer().claimFor(msg.sender, product, programIds);\\n\\n // Wrap `msg.sender`s USDC into DSU and return the DSU to `account`\\n } else if (invocation.action == PerennialAction.WRAP) {\\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\\n wrap(receiver, amount);\\n\\n // Unwrap `msg.sender`s DSU into USDC and return the USDC to `account`\\n } else if (invocation.action == PerennialAction.UNWRAP) {\\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\\n unwrap(receiver, amount);\\n\\n // Wrap `msg.sender`s USDC into DSU and deposit into `account`s `product` collateral account\\n } else if (invocation.action == PerennialAction.WRAP_AND_DEPOSIT) {\\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n wrapAndDeposit(account, product, amount);\\n }\\n\\n // Withdraw DSU from `msg.sender`s `product` collateral account, unwrap into USDC, and return the USDC to `receiver`\\n else if (invocation.action == PerennialAction.WITHDRAW_AND_UNWRAP) {\\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n withdrawAndUnwrap(receiver, product, amount);\\n }\\n }\\n }\\n\\n /**\\n * @notice Deposits `amount` DSU from `msg.sender` into `account`s `product` collateral account\\n * @param account Account to deposit funds on behalf of\\n * @param product Product to deposit funds for\\n * @param amount Amount of DSU to deposit into the collateral account\\n */\\n function depositTo(address account, IProduct product, UFixed18 amount) private {\\n // Pull the token from the `msg.sender`\\n DSU.pull(msg.sender, amount);\\n\\n // Deposit the amount to the collateral account\\n collateral.depositTo(account, product, amount);\\n }\\n\\n /**\\n * @notice Wraps `amount` USDC into DSU, pulling from `msg.sender` and sending to `receiver`\\n * @param receiver Address to receive the DSU\\n * @param amount Amount of USDC to wrap\\n */\\n function wrap(address receiver, UFixed18 amount) private {\\n // Pull USDC from the `msg.sender`\\n USDC.pull(msg.sender, amount, true);\\n\\n _wrap(receiver, amount);\\n }\\n\\n /**\\n * @notice Unwraps `amount` DSU into USDC, pulling from `msg.sender` and sending to `receiver`\\n * @param receiver Address to receive the USDC\\n * @param amount Amount of DSU to unwrap\\n */\\n function unwrap(address receiver, UFixed18 amount) private {\\n // Pull the token from the `msg.sender`\\n DSU.pull(msg.sender, amount);\\n\\n _unwrap(receiver, amount);\\n }\\n\\n /**\\n * @notice Wraps `amount` USDC from `msg.sender` into DSU, then deposits the USDC into `account`s `product` collateral account\\n * @param account Account to deposit funds on behalf of\\n * @param product Product to deposit funds for\\n * @param amount Amount of USDC to deposit into the collateral account\\n */\\n function wrapAndDeposit(address account, IProduct product, UFixed18 amount) private {\\n // Pull USDC from the `msg.sender`\\n USDC.pull(msg.sender, amount, true);\\n\\n _wrap(address(this), amount);\\n\\n // Deposit the amount to the collateral account\\n collateral.depositTo(account, product, amount);\\n }\\n\\n /**\\n * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account, then unwraps the DSU into USDC and sends it to `receiver`\\n * @param receiver Address to receive the USDC\\n * @param product Product to withdraw funds for\\n * @param amount Amount of DSU to withdraw from the collateral account\\n */\\n function withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) private {\\n // Withdraw the amount from the collateral account\\n collateral.withdrawFrom(msg.sender, address(this), product, amount);\\n\\n _unwrap(receiver, amount);\\n }\\n\\n /**\\n * @notice Helper function to wrap `amount` USDC from `msg.sender` into DSU using the batcher or reserve\\n * @param receiver Address to receive the DSU\\n * @param amount Amount of USDC to wrap\\n */\\n function _wrap(address receiver, UFixed18 amount) private {\\n // If the batcher is 0 or doesn't have enough for this wrap, go directly to the reserve\\n if (address(batcher) == address(0) || amount.gt(DSU.balanceOf(address(batcher)))) {\\n reserve.mint(amount);\\n if (receiver != address(this)) DSU.push(receiver, amount);\\n } else {\\n // Wrap the USDC into DSU and return to the receiver\\n batcher.wrap(amount, receiver);\\n }\\n }\\n\\n /**\\n * @notice Helper function to unwrap `amount` DSU into USDC and send to `receiver`\\n * @param receiver Address to receive the USDC\\n * @param amount Amount of DSU to unwrap\\n */\\n function _unwrap(address receiver, UFixed18 amount) private {\\n // If the batcher is 0 or doesn't have enough for this unwrap, go directly to the reserve\\n if (address(batcher) == address(0) || amount.gt(USDC.balanceOf(address(batcher)))) {\\n reserve.redeem(amount);\\n if (receiver != address(this)) USDC.push(receiver, amount);\\n } else {\\n // Unwrap the DSU into USDC and return to the receiver\\n batcher.unwrap(amount, receiver);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x7d1c5824eceed016f4aa161ec955e4f975eb506e35eb9ae5e351fdc0ef5bc980\",\"license\":\"BUSL-1.1\"}},\"version\":1}", - "bytecode": "0x6101406040523480156200001257600080fd5b50604051620026e9380380620026e983398101604081905262000035916200015c565b6001600160a01b0380851660805283811660c052811660e08190526040805163d8dfeb4560e01b8152905163d8dfeb45916004808201926020929091908290030181865afa1580156200008c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b29190620001c4565b6001600160a01b031661010081905260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa158015620000fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001239190620001c4565b6001600160a01b0390811660a052919091166101205250620001eb915050565b6001600160a01b03811681146200015957600080fd5b50565b600080600080608085870312156200017357600080fd5b8451620001808162000143565b6020860151909450620001938162000143565b6040860151909350620001a68162000143565b6060860151909250620001b98162000143565b939692955090935050565b600060208284031215620001d757600080fd5b8151620001e48162000143565b9392505050565b60805160a05160c05160e0516101005161012051612391620003586000396000818161014d0152818161053201528181610594015281816105f401528181610656015281816113ad01526115fe01526000818161017401528181610470015281816104d2015281816107f901528181610e440152610fe201526000818161019b0152610b1b015260008181609201528181610276015281816102ec0152818161034e015281816103ae01528181610410015281816112d30152818161134e015281816114c80152818161152b015281816115a60152611719015260008181610113015281816102ca0152818161032c0152818161044e015281816104b0015281816105100152818161057201528181610dc901528181610f0c0152818161132c015261145501526000818160ec0152818161038c015281816103ee015281816105d20152818161063401528181610ebf01528181610f570152818161158401526116a601526123916000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063bdec4a271161005b578063bdec4a2714610135578063cd3293de14610148578063d8dfeb451461016f578063f77c47911461019657600080fd5b8063025a3a291461008d5780638129fc1c146100dd57806389a30271146100e7578063a2060bcf1461010e575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100e56101bd565b005b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100e5610143366004611d16565b6106d4565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6002806101e87f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b5490565b10610227576040517f1e7a9d95000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6102507f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b829055565b60017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16156104345761031273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d1c565b61037273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b6103d473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d82565b61043473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b61049673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d1c565b6104f673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b61055873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d1c565b6105b873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b61061a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d82565b61067a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c556040518181527fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f329060200160405180910390a150565b60005b81811015610d175760008383838181106106f3576106f3611d8b565b90506020028101906107059190611dba565b61070e90611e9f565b905060018151600b81111561072557610725611f6f565b0361076057600080600083602001518060200190518101906107479190611fc3565b925092509250610758838383610daf565b505050610d04565b60028151600b81111561077557610775611f6f565b0361085f57600080600083602001518060200190518101906107979190611fc3565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff848116602483015283811660448301526064820183905293965091945092507f000000000000000000000000000000000000000000000000000000000000000090911690632644131890608401600060405180830381600087803b15801561083f57600080fd5b505af1158015610853573d6000803e3d6000fd5b50505050505050610d04565b60038151600b81111561087457610874611f6f565b036109275760008082602001518060200190518101906108949190612006565b6040517f9378bf7b00000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff831690639378bf7b906044015b600060405180830381600087803b15801561090857600080fd5b505af115801561091c573d6000803e3d6000fd5b505050505050610d04565b60048151600b81111561093c5761093c611f6f565b036109ba57600080826020015180602001905181019061095c9190612006565b6040517f2131ea4a00000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff831690632131ea4a906044016108ee565b60058151600b8111156109cf576109cf611f6f565b03610a4d5760008082602001518060200190518101906109ef9190612006565b6040517f2d2e52be00000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff831690632d2e52be906044016108ee565b60068151600b811115610a6257610a62611f6f565b03610ae0576000808260200151806020019051810190610a829190612006565b6040517fe503b00700000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff83169063e503b007906044016108ee565b60078151600b811115610af557610af5611f6f565b03610be3576000808260200151806020019051810190610b159190612034565b915091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba891906120f1565b73ffffffffffffffffffffffffffffffffffffffff16628240533384846040518463ffffffff1660e01b81526004016108ee9392919061210e565b60088151600b811115610bf857610bf8611f6f565b03610c2d576000808260200151806020019051810190610c189190612006565b91509150610c268282610ea5565b5050610d04565b60098151600b811115610c4257610c42611f6f565b03610c70576000808260200151806020019051810190610c629190612006565b91509150610c268282610ef2565b600a8151600b811115610c8557610c85611f6f565b03610cb85760008060008360200151806020019051810190610ca79190611fc3565b925092509250610758838383610f3d565b600b8151600b811115610ccd57610ccd611f6f565b03610d045760008060008360200151806020019051810190610cef9190611fc3565b925092509250610d00838383610f8a565b5050505b5080610d0f816121ad565b9150506106d7565b505050565b610d1773ffffffffffffffffffffffffffffffffffffffff84168383611048565b610d7e73ffffffffffffffffffffffffffffffffffffffff8316827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611048565b5050565b610d1782610d91836000611248565b73ffffffffffffffffffffffffffffffffffffffff86169190611048565b610df073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016338361127b565b6040517ff213159c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f213159c90606401600060405180830381600087803b158015610e8857600080fd5b505af1158015610e9c573d6000803e3d6000fd5b50505050505050565b610ee873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383600161129d565b610d7e82826112d1565b610f3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016338361127b565b610d7e8282611529565b610f8073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383600161129d565b610df030826112d1565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff8381166044830152606482018390527f00000000000000000000000000000000000000000000000000000000000000001690632644131890608401600060405180830381600087803b15801561102657600080fd5b505af115801561103a573d6000803e3d6000fd5b50505050610d178382611529565b8015806110e857506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156110c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e691906121e5565b155b611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161021e565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610d179084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611748565b6000816112635761125e64e8d4a510008461222d565b611272565b6112728364e8d4a51000611854565b90505b92915050565b610d1773ffffffffffffffffffffffffffffffffffffffff8416833084611886565b6112cb83306112ac8585611248565b73ffffffffffffffffffffffffffffffffffffffff8816929190611886565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580611379575061137961137273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006118e4565b8290611978565b1561147c576040517fa0712d68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a0712d6890602401600060405180830381600087803b15801561140657600080fd5b505af115801561141a573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff82163014610d7e57610d7e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016838361198e565b6040517f13bac8200000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f000000000000000000000000000000000000000000000000000000000000000016906313bac820906044015b600060405180830381600087803b15801561150d57600080fd5b505af1158015611521573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615806115ca57506115ca61137273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119af565b156116cd576040517fdb006a75000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063db006a7590602401600060405180830381600087803b15801561165757600080fd5b505af115801561166b573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff82163014610d7e57610d7e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383611a4b565b6040517f7647691d0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f00000000000000000000000000000000000000000000000000000000000000001690637647691d906044016114f3565b60006117aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611a789092919063ffffffff16565b805190915015610d1757808060200190518101906117c89190612241565b610d17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161021e565b60006118608284612263565b1561186c57600161186f565b60005b60ff1661187c838561222d565b6112729190612277565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112cb9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016111c6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a0823190602401602060405180830381865afa158015611954573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127291906121e5565b60006119848383611a91565b6002149392505050565b610d1773ffffffffffffffffffffffffffffffffffffffff84168383611ac6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091611272918516906370a0823190602401602060405180830381865afa158015611a22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4691906121e5565b611b1c565b610d1782611a5a836000611248565b73ffffffffffffffffffffffffffffffffffffffff86169190611ac6565b6060611a878484600085611b2d565b90505b9392505050565b6000828280821115611aa857600292505050611275565b80821015611abb57600092505050611275565b506001949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610d179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016111c6565b600061127564e8d4a510008361228f565b606082471015611bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161021e565b73ffffffffffffffffffffffffffffffffffffffff85163b611c3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161021e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611c6691906122f8565b60006040518083038185875af1925050503d8060008114611ca3576040519150601f19603f3d011682016040523d82523d6000602084013e611ca8565b606091505b5091509150611cb8828286611cc3565b979650505050505050565b60608315611cd2575081611a8a565b825115611ce25782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021e919061230a565b60008060208385031215611d2957600080fd5b823567ffffffffffffffff80821115611d4157600080fd5b818501915085601f830112611d5557600080fd5b813581811115611d6457600080fd5b8660208260051b8501011115611d7957600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112611dee57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611e4a57611e4a611df8565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e9757611e97611df8565b604052919050565b600060408236031215611eb157600080fd5b611eb9611e27565b8235600c8110611ec857600080fd5b815260208381013567ffffffffffffffff80821115611ee657600080fd5b9085019036601f830112611ef957600080fd5b813581811115611f0b57611f0b611df8565b611f3b847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611e50565b91508082523684828501011115611f5157600080fd5b80848401858401376000908201840152918301919091525092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611fc057600080fd5b50565b600080600060608486031215611fd857600080fd5b8351611fe381611f9e565b6020850151909350611ff481611f9e565b80925050604084015190509250925092565b6000806040838503121561201957600080fd5b825161202481611f9e565b6020939093015192949293505050565b6000806040838503121561204757600080fd5b825161205281611f9e565b8092505060208084015167ffffffffffffffff8082111561207257600080fd5b818601915086601f83011261208657600080fd5b81518181111561209857612098611df8565b8060051b91506120a9848301611e50565b81815291830184019184810190898411156120c357600080fd5b938501935b838510156120e1578451825293850193908501906120c8565b8096505050505050509250929050565b60006020828403121561210357600080fd5b8151611a8a81611f9e565b60006060820173ffffffffffffffffffffffffffffffffffffffff8087168452602081871681860152606060408601528291508551808452608086019250818701935060005b8181101561217057845184529382019392820192600101612154565b509198975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121de576121de61217e565b5060010190565b6000602082840312156121f757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261223c5761223c6121fe565b500490565b60006020828403121561225357600080fd5b81518015158114611a8a57600080fd5b600082612272576122726121fe565b500690565b6000821982111561228a5761228a61217e565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156122c7576122c761217e565b500290565b60005b838110156122e75781810151838201526020016122cf565b838111156112cb5750506000910152565b60008251611dee8184602087016122cc565b60208152600082518060208401526123298160408501602087016122cc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122061727f6801d5abe5d43296853dd91f7a018d3bb2c39ea20b014e388cfc0b741164736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063bdec4a271161005b578063bdec4a2714610135578063cd3293de14610148578063d8dfeb451461016f578063f77c47911461019657600080fd5b8063025a3a291461008d5780638129fc1c146100dd57806389a30271146100e7578063a2060bcf1461010e575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100e56101bd565b005b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100e5610143366004611d16565b6106d4565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6002806101e87f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b5490565b10610227576040517f1e7a9d95000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6102507f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b829055565b60017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16156104345761031273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d1c565b61037273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b6103d473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d82565b61043473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b61049673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d1c565b6104f673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b61055873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d1c565b6105b873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b61061a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000610d82565b61067a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000610d3d565b60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c556040518181527fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f329060200160405180910390a150565b60005b81811015610d175760008383838181106106f3576106f3611d8b565b90506020028101906107059190611dba565b61070e90611e9f565b905060018151600b81111561072557610725611f6f565b0361076057600080600083602001518060200190518101906107479190611fc3565b925092509250610758838383610daf565b505050610d04565b60028151600b81111561077557610775611f6f565b0361085f57600080600083602001518060200190518101906107979190611fc3565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff848116602483015283811660448301526064820183905293965091945092507f000000000000000000000000000000000000000000000000000000000000000090911690632644131890608401600060405180830381600087803b15801561083f57600080fd5b505af1158015610853573d6000803e3d6000fd5b50505050505050610d04565b60038151600b81111561087457610874611f6f565b036109275760008082602001518060200190518101906108949190612006565b6040517f9378bf7b00000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff831690639378bf7b906044015b600060405180830381600087803b15801561090857600080fd5b505af115801561091c573d6000803e3d6000fd5b505050505050610d04565b60048151600b81111561093c5761093c611f6f565b036109ba57600080826020015180602001905181019061095c9190612006565b6040517f2131ea4a00000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff831690632131ea4a906044016108ee565b60058151600b8111156109cf576109cf611f6f565b03610a4d5760008082602001518060200190518101906109ef9190612006565b6040517f2d2e52be00000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff831690632d2e52be906044016108ee565b60068151600b811115610a6257610a62611f6f565b03610ae0576000808260200151806020019051810190610a829190612006565b6040517fe503b00700000000000000000000000000000000000000000000000000000000815233600482015260248101829052919350915073ffffffffffffffffffffffffffffffffffffffff83169063e503b007906044016108ee565b60078151600b811115610af557610af5611f6f565b03610be3576000808260200151806020019051810190610b159190612034565b915091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba891906120f1565b73ffffffffffffffffffffffffffffffffffffffff16628240533384846040518463ffffffff1660e01b81526004016108ee9392919061210e565b60088151600b811115610bf857610bf8611f6f565b03610c2d576000808260200151806020019051810190610c189190612006565b91509150610c268282610ea5565b5050610d04565b60098151600b811115610c4257610c42611f6f565b03610c70576000808260200151806020019051810190610c629190612006565b91509150610c268282610ef2565b600a8151600b811115610c8557610c85611f6f565b03610cb85760008060008360200151806020019051810190610ca79190611fc3565b925092509250610758838383610f3d565b600b8151600b811115610ccd57610ccd611f6f565b03610d045760008060008360200151806020019051810190610cef9190611fc3565b925092509250610d00838383610f8a565b5050505b5080610d0f816121ad565b9150506106d7565b505050565b610d1773ffffffffffffffffffffffffffffffffffffffff84168383611048565b610d7e73ffffffffffffffffffffffffffffffffffffffff8316827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611048565b5050565b610d1782610d91836000611248565b73ffffffffffffffffffffffffffffffffffffffff86169190611048565b610df073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016338361127b565b6040517ff213159c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f213159c90606401600060405180830381600087803b158015610e8857600080fd5b505af1158015610e9c573d6000803e3d6000fd5b50505050505050565b610ee873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383600161129d565b610d7e82826112d1565b610f3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016338361127b565b610d7e8282611529565b610f8073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383600161129d565b610df030826112d1565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff8381166044830152606482018390527f00000000000000000000000000000000000000000000000000000000000000001690632644131890608401600060405180830381600087803b15801561102657600080fd5b505af115801561103a573d6000803e3d6000fd5b50505050610d178382611529565b8015806110e857506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156110c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e691906121e5565b155b611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161021e565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610d179084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611748565b6000816112635761125e64e8d4a510008461222d565b611272565b6112728364e8d4a51000611854565b90505b92915050565b610d1773ffffffffffffffffffffffffffffffffffffffff8416833084611886565b6112cb83306112ac8585611248565b73ffffffffffffffffffffffffffffffffffffffff8816929190611886565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580611379575061137961137273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006118e4565b8290611978565b1561147c576040517fa0712d68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a0712d6890602401600060405180830381600087803b15801561140657600080fd5b505af115801561141a573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff82163014610d7e57610d7e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016838361198e565b6040517f13bac8200000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f000000000000000000000000000000000000000000000000000000000000000016906313bac820906044015b600060405180830381600087803b15801561150d57600080fd5b505af1158015611521573d6000803e3d6000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615806115ca57506115ca61137273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119af565b156116cd576040517fdb006a75000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063db006a7590602401600060405180830381600087803b15801561165757600080fd5b505af115801561166b573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff82163014610d7e57610d7e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383611a4b565b6040517f7647691d0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f00000000000000000000000000000000000000000000000000000000000000001690637647691d906044016114f3565b60006117aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611a789092919063ffffffff16565b805190915015610d1757808060200190518101906117c89190612241565b610d17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161021e565b60006118608284612263565b1561186c57600161186f565b60005b60ff1661187c838561222d565b6112729190612277565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112cb9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016111c6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a0823190602401602060405180830381865afa158015611954573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127291906121e5565b60006119848383611a91565b6002149392505050565b610d1773ffffffffffffffffffffffffffffffffffffffff84168383611ac6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091611272918516906370a0823190602401602060405180830381865afa158015611a22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4691906121e5565b611b1c565b610d1782611a5a836000611248565b73ffffffffffffffffffffffffffffffffffffffff86169190611ac6565b6060611a878484600085611b2d565b90505b9392505050565b6000828280821115611aa857600292505050611275565b80821015611abb57600092505050611275565b506001949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610d179084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016111c6565b600061127564e8d4a510008361228f565b606082471015611bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161021e565b73ffffffffffffffffffffffffffffffffffffffff85163b611c3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161021e565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611c6691906122f8565b60006040518083038185875af1925050503d8060008114611ca3576040519150601f19603f3d011682016040523d82523d6000602084013e611ca8565b606091505b5091509150611cb8828286611cc3565b979650505050505050565b60608315611cd2575081611a8a565b825115611ce25782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161021e919061230a565b60008060208385031215611d2957600080fd5b823567ffffffffffffffff80821115611d4157600080fd5b818501915085601f830112611d5557600080fd5b813581811115611d6457600080fd5b8660208260051b8501011115611d7957600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112611dee57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611e4a57611e4a611df8565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e9757611e97611df8565b604052919050565b600060408236031215611eb157600080fd5b611eb9611e27565b8235600c8110611ec857600080fd5b815260208381013567ffffffffffffffff80821115611ee657600080fd5b9085019036601f830112611ef957600080fd5b813581811115611f0b57611f0b611df8565b611f3b847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611e50565b91508082523684828501011115611f5157600080fd5b80848401858401376000908201840152918301919091525092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611fc057600080fd5b50565b600080600060608486031215611fd857600080fd5b8351611fe381611f9e565b6020850151909350611ff481611f9e565b80925050604084015190509250925092565b6000806040838503121561201957600080fd5b825161202481611f9e565b6020939093015192949293505050565b6000806040838503121561204757600080fd5b825161205281611f9e565b8092505060208084015167ffffffffffffffff8082111561207257600080fd5b818601915086601f83011261208657600080fd5b81518181111561209857612098611df8565b8060051b91506120a9848301611e50565b81815291830184019184810190898411156120c357600080fd5b938501935b838510156120e1578451825293850193908501906120c8565b8096505050505050509250929050565b60006020828403121561210357600080fd5b8151611a8a81611f9e565b60006060820173ffffffffffffffffffffffffffffffffffffffff8087168452602081871681860152606060408601528291508551808452608086019250818701935060005b8181101561217057845184529382019392820192600101612154565b509198975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121de576121de61217e565b5060010190565b6000602082840312156121f757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261223c5761223c6121fe565b500490565b60006020828403121561225357600080fd5b81518015158114611a8a57600080fd5b600082612272576122726121fe565b500690565b6000821982111561228a5761228a61217e565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156122c7576122c761217e565b500290565b60005b838110156122e75781810151838201526020016122cf565b838111156112cb5750506000910152565b60008251611dee8184602087016122cc565b60208152600082518060208401526123298160408501602087016122cc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122061727f6801d5abe5d43296853dd91f7a018d3bb2c39ea20b014e388cfc0b741164736f6c634300080f0033", + "numDeployments": 3, + "solcInputHash": "181d5952a5d0fca85831e55cf8991318", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"Token6\",\"name\":\"usdc\",\"type\":\"address\"},{\"internalType\":\"contract IBatcher\",\"name\":\"_batcher\",\"type\":\"address\"},{\"internalType\":\"contract IEmptySetReserve\",\"name\":\"_reserve\",\"type\":\"address\"},{\"internalType\":\"contract IController\",\"name\":\"_controller\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"MultiInvokerRollupInvalidCalldataError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"UInitializableAlreadyInitializedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UInitializableNotInitializingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UInitializableZeroVersionError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"AddressAddedToCache\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"DSU\",\"outputs\":[{\"internalType\":\"Token18\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDC\",\"outputs\":[{\"internalType\":\"Token6\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"addressCache\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"addressLookup\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batcher\",\"outputs\":[{\"internalType\":\"contract IBatcher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract ICollateral\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"enum IMultiInvoker.PerennialAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"args\",\"type\":\"bytes\"}],\"internalType\":\"struct IMultiInvoker.Invocation[]\",\"name\":\"invocations\",\"type\":\"tuple[]\"}],\"name\":\"invoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reserve\",\"outputs\":[{\"internalType\":\"contract IEmptySetReserve\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"MultiInvokerRollupInvalidCalldataError()\":[{\"details\":\"reverts when calldata has an issue. causes: length of bytes in a uint > || cache index empty\"}]},\"kind\":\"dev\",\"methods\":{\"initialize()\":{\"details\":\"Must be called atomically as part of the upgradeable proxy deployment to avoid front-running\"},\"invoke((uint8,bytes)[])\":{\"params\":{\"invocations\":\"The list of invocations to execute in order\"}}},\"stateVariables\":{\"addressCache\":{\"details\":\"array of all stored addresses (users, products, vaults, etc) for calldata packing\"},\"addressLookup\":{\"details\":\"index lookup of above array for constructing calldata\"}},\"title\":\"A calldata-optimized implementation of the Perennial MultiInvoker \",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"initialize()\":{\"notice\":\"Initializes the contract state\"},\"invoke((uint8,bytes)[])\":{\"notice\":\"Executes a list of invocations in order\"}},\"notice\":\"Retains same functionality and `invoke` entry point from inherited MultiInvoker\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/multiinvoker/MultiInvokerRollup.sol\":\"MultiInvokerRollup\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"../interfaces/IEmptySetReserve.sol\\\";\\n\\ninterface IBatcher {\\n event Wrap(address indexed to, UFixed18 amount);\\n event Unwrap(address indexed to, UFixed18 amount);\\n event Rebalance(UFixed18 newMinted, UFixed18 newRedeemed);\\n event Close(UFixed18 amount);\\n\\n error BatcherNotImplementedError();\\n error BatcherBalanceMismatchError(UFixed18 oldBalance, UFixed18 newBalance);\\n\\n function RESERVE() external view returns (IEmptySetReserve); // solhint-disable-line func-name-mixedcase\\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\\n function totalBalance() external view returns (UFixed18);\\n function wrap(UFixed18 amount, address to) external;\\n function unwrap(UFixed18 amount, address to) external;\\n function rebalance() external;\\n}\\n\",\"keccak256\":\"0xb9c0b0fc0dfcd44492b029ede04d304f6906b030cb925dc0fc2579e8c58d9734\",\"license\":\"Apache-2.0\"},\"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\ninterface IEmptySetReserve {\\n event Redeem(address indexed account, uint256 costAmount, uint256 redeemAmount);\\n event Mint(address indexed account, uint256 mintAmount, uint256 costAmount);\\n event Repay(address indexed account, uint256 repayAmount);\\n\\n function debt(address borrower) external view returns (UFixed18);\\n function repay(address borrower, UFixed18 amount) external;\\n function mint(UFixed18 amount) external;\\n function redeem(UFixed18 amount) external;\\n}\\n\",\"keccak256\":\"0xdb96e26082a471c7803e892ecd8d2877f23cd9e31f13a3e407dd5f8909078864\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\n\\ninterface IOracleProvider {\\n /// @dev Error for invalid oracle round\\n error InvalidOracleRound();\\n\\n /// @dev A singular oracle version with its corresponding data\\n struct OracleVersion {\\n /// @dev The iterative version\\n uint256 version;\\n\\n /// @dev the timestamp of the oracle update\\n uint256 timestamp;\\n\\n /// @dev The oracle price of the corresponding version\\n Fixed18 price;\\n }\\n\\n function sync() external returns (OracleVersion memory);\\n function currentVersion() external view returns (OracleVersion memory);\\n function atVersion(uint256 oracleVersion) external view returns (OracleVersion memory);\\n}\\n\",\"keccak256\":\"0x11e8ebb40917dcce08a6366e6fa8d25b037552d4ea66b96c13e6f45b1f817c52\",\"license\":\"Apache-2.0\"},\"@equilibria/root/control/unstructured/UInitializable.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../../storage/UStorage.sol\\\";\\n\\n/**\\n * @title UInitializable\\n * @notice Library to manage the initialization lifecycle of upgradeable contracts\\n * @dev `UInitializable` allows the creation of pseudo-constructors for upgradeable contracts. One\\n * `initializer` should be declared per top-level contract. Child contracts can use the `onlyInitializer`\\n * modifier to tag their internal initialization functions to ensure that they can only be called\\n * from a top-level `initializer` or a constructor.\\n */\\nabstract contract UInitializable {\\n error UInitializableZeroVersionError();\\n error UInitializableAlreadyInitializedError(uint256 version);\\n error UInitializableNotInitializingError();\\n\\n event Initialized(uint256 version);\\n\\n /// @dev The initialized flag\\n Uint256Storage private constant _version = Uint256Storage.wrap(keccak256(\\\"equilibria.root.UInitializable.version\\\"));\\n\\n /// @dev The initializing flag\\n BoolStorage private constant _initializing = BoolStorage.wrap(keccak256(\\\"equilibria.root.UInitializable.initializing\\\"));\\n\\n /// @dev Can only be called once per version, `version` is 1-indexed\\n modifier initializer(uint256 version) {\\n if (version == 0) revert UInitializableZeroVersionError();\\n if (_version.read() >= version) revert UInitializableAlreadyInitializedError(version);\\n\\n _version.store(version);\\n _initializing.store(true);\\n\\n _;\\n\\n _initializing.store(false);\\n emit Initialized(version);\\n }\\n\\n /// @dev Can only be called from an initializer or constructor\\n modifier onlyInitializer() {\\n if (!_constructing() && !_initializing.read()) revert UInitializableNotInitializingError();\\n _;\\n }\\n\\n /**\\n * @notice Returns whether the contract is currently being constructed\\n * @dev {Address.isContract} returns false for contracts currently in the process of being constructed\\n * @return Whether the contract is currently being constructed\\n */\\n function _constructing() private view returns (bool) {\\n return !Address.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd2743d8fcc220ed2ccdc0bba1db0a3e107741bd5c0cac47ca8c0b5a00ba2fd7f\",\"license\":\"Apache-2.0\"},\"@equilibria/root/curve/CurveMath.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../number/types/UFixed18.sol\\\";\\nimport \\\"../number/types/Fixed18.sol\\\";\\n\\n/**\\n * @title CurveMath\\n * @notice Library for managing math operations for utilization curves.\\n */\\nlibrary CurveMath {\\n error CurveMathOutOfBoundsError();\\n\\n /**\\n * @notice Computes a linear interpolation between two points\\n * @param startX First point's x-coordinate\\n * @param startY First point's y-coordinate\\n * @param endX Second point's x-coordinate\\n * @param endY Second point's y-coordinate\\n * @param targetX x-coordinate to interpolate\\n * @return y-coordinate for `targetX` along the line from (`startX`, `startY`) -> (`endX`, `endY`)\\n */\\n function linearInterpolation(\\n UFixed18 startX,\\n Fixed18 startY,\\n UFixed18 endX,\\n Fixed18 endY,\\n UFixed18 targetX\\n ) internal pure returns (Fixed18) {\\n if (targetX.lt(startX) || targetX.gt(endX)) revert CurveMathOutOfBoundsError();\\n\\n UFixed18 xRange = endX.sub(startX);\\n Fixed18 yRange = endY.sub(startY);\\n UFixed18 xRatio = targetX.sub(startX).div(xRange);\\n return yRange.mul(Fixed18Lib.from(xRatio)).add(startY);\\n }\\n}\\n\",\"keccak256\":\"0x60d159f9ddf0dbe81124ecad58bba734b4cf82877637ff8d9d7f3e92f2da4ded\",\"license\":\"Apache-2.0\"},\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../CurveMath.sol\\\";\\nimport \\\"../../number/types/PackedUFixed18.sol\\\";\\nimport \\\"../../number/types/PackedFixed18.sol\\\";\\n\\n/// @dev JumpRateUtilizationCurve type\\nstruct JumpRateUtilizationCurve {\\n PackedFixed18 minRate;\\n PackedFixed18 maxRate;\\n PackedFixed18 targetRate;\\n PackedUFixed18 targetUtilization;\\n}\\nusing JumpRateUtilizationCurveLib for JumpRateUtilizationCurve global;\\ntype JumpRateUtilizationCurveStorage is bytes32;\\nusing JumpRateUtilizationCurveStorageLib for JumpRateUtilizationCurveStorage global;\\n\\n/**\\n * @title JumpRateUtilizationCurveLib\\n * @notice Library for the Jump Rate utilization curve type\\n */\\nlibrary JumpRateUtilizationCurveLib {\\n /**\\n * @notice Computes the corresponding rate for a utilization ratio\\n * @param utilization The utilization ratio\\n * @return The corresponding rate\\n */\\n function compute(JumpRateUtilizationCurve memory self, UFixed18 utilization) internal pure returns (Fixed18) {\\n UFixed18 targetUtilization = self.targetUtilization.unpack();\\n if (utilization.lt(targetUtilization)) {\\n return CurveMath.linearInterpolation(\\n UFixed18Lib.ZERO,\\n self.minRate.unpack(),\\n targetUtilization,\\n self.targetRate.unpack(),\\n utilization\\n );\\n }\\n if (utilization.lt(UFixed18Lib.ONE)) {\\n return CurveMath.linearInterpolation(\\n targetUtilization,\\n self.targetRate.unpack(),\\n UFixed18Lib.ONE,\\n self.maxRate.unpack(),\\n utilization\\n );\\n }\\n return self.maxRate.unpack();\\n }\\n}\\n\\nlibrary JumpRateUtilizationCurveStorageLib {\\n function read(JumpRateUtilizationCurveStorage self) internal view returns (JumpRateUtilizationCurve memory) {\\n return _storagePointer(self);\\n }\\n\\n function store(JumpRateUtilizationCurveStorage self, JumpRateUtilizationCurve memory value) internal {\\n JumpRateUtilizationCurve storage storagePointer = _storagePointer(self);\\n\\n storagePointer.minRate = value.minRate;\\n storagePointer.maxRate = value.maxRate;\\n storagePointer.targetRate = value.targetRate;\\n storagePointer.targetUtilization = value.targetUtilization;\\n }\\n\\n function _storagePointer(JumpRateUtilizationCurveStorage self)\\n private pure returns (JumpRateUtilizationCurve storage pointer) {\\n assembly { pointer.slot := self }\\n }\\n}\",\"keccak256\":\"0xae202813874bc306d51b3dab8194c86f6483bb20bf1f673ddaee16aa8de567ff\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/Fixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/SignedMath.sol\\\";\\nimport \\\"./UFixed18.sol\\\";\\nimport \\\"./PackedFixed18.sol\\\";\\n\\n/// @dev Fixed18 type\\ntype Fixed18 is int256;\\nusing Fixed18Lib for Fixed18 global;\\ntype Fixed18Storage is bytes32;\\nusing Fixed18StorageLib for Fixed18Storage global;\\n\\n/**\\n * @title Fixed18Lib\\n * @notice Library for the signed fixed-decimal type.\\n */\\nlibrary Fixed18Lib {\\n error Fixed18OverflowError(uint256 value);\\n error Fixed18PackingOverflowError(int256 value);\\n error Fixed18PackingUnderflowError(int256 value);\\n\\n int256 private constant BASE = 1e18;\\n Fixed18 public constant ZERO = Fixed18.wrap(0);\\n Fixed18 public constant ONE = Fixed18.wrap(BASE);\\n Fixed18 public constant NEG_ONE = Fixed18.wrap(-1 * BASE);\\n Fixed18 public constant MAX = Fixed18.wrap(type(int256).max);\\n Fixed18 public constant MIN = Fixed18.wrap(type(int256).min);\\n\\n /**\\n * @notice Creates a signed fixed-decimal from an unsigned fixed-decimal\\n * @param a Unsigned fixed-decimal\\n * @return New signed fixed-decimal\\n */\\n function from(UFixed18 a) internal pure returns (Fixed18) {\\n uint256 value = UFixed18.unwrap(a);\\n if (value > uint256(type(int256).max)) revert Fixed18OverflowError(value);\\n return Fixed18.wrap(int256(value));\\n }\\n\\n /**\\n * @notice Creates a signed fixed-decimal from a sign and an unsigned fixed-decimal\\n * @param s Sign\\n * @param m Unsigned fixed-decimal magnitude\\n * @return New signed fixed-decimal\\n */\\n function from(int256 s, UFixed18 m) internal pure returns (Fixed18) {\\n if (s > 0) return from(m);\\n if (s < 0) return Fixed18.wrap(-1 * Fixed18.unwrap(from(m)));\\n return ZERO;\\n }\\n\\n /**\\n * @notice Creates a signed fixed-decimal from a signed integer\\n * @param a Signed number\\n * @return New signed fixed-decimal\\n */\\n function from(int256 a) internal pure returns (Fixed18) {\\n return Fixed18.wrap(a * BASE);\\n }\\n\\n /**\\n * @notice Creates a packed signed fixed-decimal from an signed fixed-decimal\\n * @param a signed fixed-decimal\\n * @return New packed signed fixed-decimal\\n */\\n function pack(Fixed18 a) internal pure returns (PackedFixed18) {\\n int256 value = Fixed18.unwrap(a);\\n if (value > type(int128).max) revert Fixed18PackingOverflowError(value);\\n if (value < type(int128).min) revert Fixed18PackingUnderflowError(value);\\n return PackedFixed18.wrap(int128(value));\\n }\\n\\n /**\\n * @notice Returns whether the signed fixed-decimal is equal to zero.\\n * @param a Signed fixed-decimal\\n * @return Whether the signed fixed-decimal is zero.\\n */\\n function isZero(Fixed18 a) internal pure returns (bool) {\\n return Fixed18.unwrap(a) == 0;\\n }\\n\\n /**\\n * @notice Adds two signed fixed-decimals `a` and `b` together\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Resulting summed signed fixed-decimal\\n */\\n function add(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) + Fixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Subtracts signed fixed-decimal `b` from `a`\\n * @param a Signed fixed-decimal to subtract from\\n * @param b Signed fixed-decimal to subtract\\n * @return Resulting subtracted signed fixed-decimal\\n */\\n function sub(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) - Fixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Multiplies two signed fixed-decimals `a` and `b` together\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Resulting multiplied signed fixed-decimal\\n */\\n function mul(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / BASE);\\n }\\n\\n /**\\n * @notice Divides signed fixed-decimal `a` by `b`\\n * @param a Signed fixed-decimal to divide\\n * @param b Signed fixed-decimal to divide by\\n * @return Resulting divided signed fixed-decimal\\n */\\n function div(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) * BASE / Fixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Divides unsigned fixed-decimal `a` by `b`\\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0`, `MAX` for `n/0`, and `MIN` for `-n/0`.\\n * @param a Unsigned fixed-decimal to divide\\n * @param b Unsigned fixed-decimal to divide by\\n * @return Resulting divided unsigned fixed-decimal\\n */\\n function unsafeDiv(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n if (isZero(b)) {\\n if (gt(a, ZERO)) return MAX;\\n if (lt(a, ZERO)) return MIN;\\n return ONE;\\n } else {\\n return div(a, b);\\n }\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First signed fixed-decimal\\n * @param b Signed number to multiply by\\n * @param c Signed number to divide by\\n * @return Resulting computation\\n */\\n function muldiv(Fixed18 a, int256 b, int256 c) internal pure returns (Fixed18) {\\n return muldiv(a, Fixed18.wrap(b), Fixed18.wrap(c));\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First signed fixed-decimal\\n * @param b Signed fixed-decimal to multiply by\\n * @param c Signed fixed-decimal to divide by\\n * @return Resulting computation\\n */\\n function muldiv(Fixed18 a, Fixed18 b, Fixed18 c) internal pure returns (Fixed18) {\\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / Fixed18.unwrap(c));\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is equal to `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is equal to `b`\\n */\\n function eq(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 1;\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is greater than `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is greater than `b`\\n */\\n function gt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 2;\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is less than `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is less than `b`\\n */\\n function lt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 0;\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is greater than or equal to `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is greater than or equal to `b`\\n */\\n function gte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return gt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Returns whether signed fixed-decimal `a` is less than or equal to `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Whether `a` is less than or equal to `b`\\n */\\n function lte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n return lt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Compares the signed fixed-decimals `a` and `b`\\n * @dev Returns: 2 for greater than\\n * 1 for equal to\\n * 0 for less than\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Compare result of `a` and `b`\\n */\\n function compare(Fixed18 a, Fixed18 b) internal pure returns (uint256) {\\n (int256 au, int256 bu) = (Fixed18.unwrap(a), Fixed18.unwrap(b));\\n if (au > bu) return 2;\\n if (au < bu) return 0;\\n return 1;\\n }\\n\\n /**\\n * @notice Returns a signed fixed-decimal representing the ratio of `a` over `b`\\n * @param a First signed number\\n * @param b Second signed number\\n * @return Ratio of `a` over `b`\\n */\\n function ratio(int256 a, int256 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(a * BASE / b);\\n }\\n\\n /**\\n * @notice Returns the minimum of signed fixed-decimals `a` and `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Minimum of `a` and `b`\\n */\\n function min(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(SignedMath.min(Fixed18.unwrap(a), Fixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Returns the maximum of signed fixed-decimals `a` and `b`\\n * @param a First signed fixed-decimal\\n * @param b Second signed fixed-decimal\\n * @return Maximum of `a` and `b`\\n */\\n function max(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n return Fixed18.wrap(SignedMath.max(Fixed18.unwrap(a), Fixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Converts the signed fixed-decimal into an integer, truncating any decimal portion\\n * @param a Signed fixed-decimal\\n * @return Truncated signed number\\n */\\n function truncate(Fixed18 a) internal pure returns (int256) {\\n return Fixed18.unwrap(a) / BASE;\\n }\\n\\n /**\\n * @notice Returns the sign of the signed fixed-decimal\\n * @dev Returns: -1 for negative\\n * 0 for zero\\n * 1 for positive\\n * @param a Signed fixed-decimal\\n * @return Sign of the signed fixed-decimal\\n */\\n function sign(Fixed18 a) internal pure returns (int256) {\\n if (Fixed18.unwrap(a) > 0) return 1;\\n if (Fixed18.unwrap(a) < 0) return -1;\\n return 0;\\n }\\n\\n /**\\n * @notice Returns the absolute value of the signed fixed-decimal\\n * @param a Signed fixed-decimal\\n * @return Absolute value of the signed fixed-decimal\\n */\\n function abs(Fixed18 a) internal pure returns (UFixed18) {\\n return UFixed18.wrap(SignedMath.abs(Fixed18.unwrap(a)));\\n }\\n}\\n\\nlibrary Fixed18StorageLib {\\n function read(Fixed18Storage self) internal view returns (Fixed18 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(Fixed18Storage self, Fixed18 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x613587461ef3437ef33229cdda7d34ea746278721baf06e20b2e43977f43174d\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/PackedFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./Fixed18.sol\\\";\\n\\n/// @dev PackedFixed18 type\\ntype PackedFixed18 is int128;\\nusing PackedFixed18Lib for PackedFixed18 global;\\n\\n/**\\n * @title PackedFixed18Lib\\n * @dev A packed version of the Fixed18 which takes up half the storage space (two PackedFixed18 can be packed\\n * into a single slot). Only valid within the range -1.7014118e+20 <= x <= 1.7014118e+20.\\n * @notice Library for the packed signed fixed-decimal type.\\n */\\nlibrary PackedFixed18Lib {\\n PackedFixed18 public constant MAX = PackedFixed18.wrap(type(int128).max);\\n PackedFixed18 public constant MIN = PackedFixed18.wrap(type(int128).min);\\n\\n /**\\n * @notice Creates an unpacked signed fixed-decimal from a packed signed fixed-decimal\\n * @param self packed signed fixed-decimal\\n * @return New unpacked signed fixed-decimal\\n */\\n function unpack(PackedFixed18 self) internal pure returns (Fixed18) {\\n return Fixed18.wrap(int256(PackedFixed18.unwrap(self)));\\n }\\n}\\n\",\"keccak256\":\"0xb52960cc8e3132e45d342bbbb1c6a96219022cd8557997933bd8250170268b64\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/PackedUFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./UFixed18.sol\\\";\\n\\n/// @dev PackedUFixed18 type\\ntype PackedUFixed18 is uint128;\\nusing PackedUFixed18Lib for PackedUFixed18 global;\\n\\n/**\\n * @title PackedUFixed18Lib\\n * @dev A packed version of the UFixed18 which takes up half the storage space (two PackedUFixed18 can be packed\\n * into a single slot). Only valid within the range 0 <= x <= 3.4028237e+20.\\n * @notice Library for the packed unsigned fixed-decimal type.\\n */\\nlibrary PackedUFixed18Lib {\\n PackedUFixed18 public constant MAX = PackedUFixed18.wrap(type(uint128).max);\\n\\n /**\\n * @notice Creates an unpacked unsigned fixed-decimal from a packed unsigned fixed-decimal\\n * @param self packed unsigned fixed-decimal\\n * @return New unpacked unsigned fixed-decimal\\n */\\n function unpack(PackedUFixed18 self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(PackedUFixed18.unwrap(self)));\\n }\\n}\\n\",\"keccak256\":\"0xb5c5cd32d6530b2fe75228b6be32ebcb7762f6d7988b85a6b85a289ce8256d51\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/UFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"./Fixed18.sol\\\";\\nimport \\\"./PackedUFixed18.sol\\\";\\n\\n/// @dev UFixed18 type\\ntype UFixed18 is uint256;\\nusing UFixed18Lib for UFixed18 global;\\ntype UFixed18Storage is bytes32;\\nusing UFixed18StorageLib for UFixed18Storage global;\\n\\n/**\\n * @title UFixed18Lib\\n * @notice Library for the unsigned fixed-decimal type.\\n */\\nlibrary UFixed18Lib {\\n error UFixed18UnderflowError(int256 value);\\n error UFixed18PackingOverflowError(uint256 value);\\n\\n uint256 private constant BASE = 1e18;\\n UFixed18 public constant ZERO = UFixed18.wrap(0);\\n UFixed18 public constant ONE = UFixed18.wrap(BASE);\\n UFixed18 public constant MAX = UFixed18.wrap(type(uint256).max);\\n\\n /**\\n * @notice Creates a unsigned fixed-decimal from a signed fixed-decimal\\n * @param a Signed fixed-decimal\\n * @return New unsigned fixed-decimal\\n */\\n function from(Fixed18 a) internal pure returns (UFixed18) {\\n int256 value = Fixed18.unwrap(a);\\n if (value < 0) revert UFixed18UnderflowError(value);\\n return UFixed18.wrap(uint256(value));\\n }\\n\\n /**\\n * @notice Creates a unsigned fixed-decimal from a unsigned integer\\n * @param a Unsigned number\\n * @return New unsigned fixed-decimal\\n */\\n function from(uint256 a) internal pure returns (UFixed18) {\\n return UFixed18.wrap(a * BASE);\\n }\\n\\n /**\\n * @notice Creates a packed unsigned fixed-decimal from an unsigned fixed-decimal\\n * @param a unsigned fixed-decimal\\n * @return New packed unsigned fixed-decimal\\n */\\n function pack(UFixed18 a) internal pure returns (PackedUFixed18) {\\n uint256 value = UFixed18.unwrap(a);\\n if (value > type(uint128).max) revert UFixed18PackingOverflowError(value);\\n return PackedUFixed18.wrap(uint128(value));\\n }\\n\\n /**\\n * @notice Returns whether the unsigned fixed-decimal is equal to zero.\\n * @param a Unsigned fixed-decimal\\n * @return Whether the unsigned fixed-decimal is zero.\\n */\\n function isZero(UFixed18 a) internal pure returns (bool) {\\n return UFixed18.unwrap(a) == 0;\\n }\\n\\n /**\\n * @notice Adds two unsigned fixed-decimals `a` and `b` together\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Resulting summed unsigned fixed-decimal\\n */\\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Subtracts unsigned fixed-decimal `b` from `a`\\n * @param a Unsigned fixed-decimal to subtract from\\n * @param b Unsigned fixed-decimal to subtract\\n * @return Resulting subtracted unsigned fixed-decimal\\n */\\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Multiplies two unsigned fixed-decimals `a` and `b` together\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Resulting multiplied unsigned fixed-decimal\\n */\\n function mul(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / BASE);\\n }\\n\\n /**\\n * @notice Divides unsigned fixed-decimal `a` by `b`\\n * @param a Unsigned fixed-decimal to divide\\n * @param b Unsigned fixed-decimal to divide by\\n * @return Resulting divided unsigned fixed-decimal\\n */\\n function div(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) * BASE / UFixed18.unwrap(b));\\n }\\n\\n /**\\n * @notice Divides unsigned fixed-decimal `a` by `b`\\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0` and `MAX` for `n/0`.\\n * @param a Unsigned fixed-decimal to divide\\n * @param b Unsigned fixed-decimal to divide by\\n * @return Resulting divided unsigned fixed-decimal\\n */\\n function unsafeDiv(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n if (isZero(b)) {\\n return isZero(a) ? ONE : MAX;\\n } else {\\n return div(a, b);\\n }\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First unsigned fixed-decimal\\n * @param b Unsigned number to multiply by\\n * @param c Unsigned number to divide by\\n * @return Resulting computation\\n */\\n function muldiv(UFixed18 a, uint256 b, uint256 c) internal pure returns (UFixed18) {\\n return muldiv(a, UFixed18.wrap(b), UFixed18.wrap(c));\\n }\\n\\n /**\\n * @notice Computes a * b / c without loss of precision due to BASE conversion\\n * @param a First unsigned fixed-decimal\\n * @param b Unsigned fixed-decimal to multiply by\\n * @param c Unsigned fixed-decimal to divide by\\n * @return Resulting computation\\n */\\n function muldiv(UFixed18 a, UFixed18 b, UFixed18 c) internal pure returns (UFixed18) {\\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / UFixed18.unwrap(c));\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is equal to `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is equal to `b`\\n */\\n function eq(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 1;\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is greater than `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is greater than `b`\\n */\\n function gt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 2;\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is less than `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is less than `b`\\n */\\n function lt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return compare(a, b) == 0;\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is greater than or equal to `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is greater than or equal to `b`\\n */\\n function gte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return gt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Returns whether unsigned fixed-decimal `a` is less than or equal to `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Whether `a` is less than or equal to `b`\\n */\\n function lte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n return lt(a, b) || eq(a, b);\\n }\\n\\n /**\\n * @notice Compares the unsigned fixed-decimals `a` and `b`\\n * @dev Returns: 2 for greater than\\n * 1 for equal to\\n * 0 for less than\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Compare result of `a` and `b`\\n */\\n function compare(UFixed18 a, UFixed18 b) internal pure returns (uint256) {\\n (uint256 au, uint256 bu) = (UFixed18.unwrap(a), UFixed18.unwrap(b));\\n if (au > bu) return 2;\\n if (au < bu) return 0;\\n return 1;\\n }\\n\\n /**\\n * @notice Returns a unsigned fixed-decimal representing the ratio of `a` over `b`\\n * @param a First unsigned number\\n * @param b Second unsigned number\\n * @return Ratio of `a` over `b`\\n */\\n function ratio(uint256 a, uint256 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(a * BASE / b);\\n }\\n\\n /**\\n * @notice Returns the minimum of unsigned fixed-decimals `a` and `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Minimum of `a` and `b`\\n */\\n function min(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(Math.min(UFixed18.unwrap(a), UFixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Returns the maximum of unsigned fixed-decimals `a` and `b`\\n * @param a First unsigned fixed-decimal\\n * @param b Second unsigned fixed-decimal\\n * @return Maximum of `a` and `b`\\n */\\n function max(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n return UFixed18.wrap(Math.max(UFixed18.unwrap(a), UFixed18.unwrap(b)));\\n }\\n\\n /**\\n * @notice Converts the unsigned fixed-decimal into an integer, truncating any decimal portion\\n * @param a Unsigned fixed-decimal\\n * @return Truncated unsigned number\\n */\\n function truncate(UFixed18 a) internal pure returns (uint256) {\\n return UFixed18.unwrap(a) / BASE;\\n }\\n}\\n\\nlibrary UFixed18StorageLib {\\n function read(UFixed18Storage self) internal view returns (UFixed18 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(UFixed18Storage self, UFixed18 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8ebef1e6c717f565b9ed545a876b5692b4007e6485c99f39d363f7405e591792\",\"license\":\"Apache-2.0\"},\"@equilibria/root/storage/UStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../number/types/UFixed18.sol\\\";\\n\\n/// @dev Stored boolean slot\\ntype BoolStorage is bytes32;\\nusing BoolStorageLib for BoolStorage global;\\n\\n/// @dev Stored uint256 slot\\ntype Uint256Storage is bytes32;\\nusing Uint256StorageLib for Uint256Storage global;\\n\\n/// @dev Stored int256 slot\\ntype Int256Storage is bytes32;\\nusing Int256StorageLib for Int256Storage global;\\n\\n/// @dev Stored address slot\\ntype AddressStorage is bytes32;\\nusing AddressStorageLib for AddressStorage global;\\n\\n/// @dev Stored bytes32 slot\\ntype Bytes32Storage is bytes32;\\nusing Bytes32StorageLib for Bytes32Storage global;\\n\\n/**\\n * @title BoolStorageLib\\n * @notice Library to manage storage and retrival of a boolean at a fixed storage slot\\n */\\nlibrary BoolStorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored bool value\\n */\\n function read(BoolStorage self) internal view returns (bool value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value boolean value to store\\n */\\n function store(BoolStorage self, bool value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title Uint256StorageLib\\n * @notice Library to manage storage and retrival of an uint256 at a fixed storage slot\\n */\\nlibrary Uint256StorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored uint256 value\\n */\\n function read(Uint256Storage self) internal view returns (uint256 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value uint256 value to store\\n */\\n function store(Uint256Storage self, uint256 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title Int256StorageLib\\n * @notice Library to manage storage and retrival of an int256 at a fixed storage slot\\n */\\nlibrary Int256StorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored int256 value\\n */\\n function read(Int256Storage self) internal view returns (int256 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value int256 value to store\\n */\\n function store(Int256Storage self, int256 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title AddressStorageLib\\n * @notice Library to manage storage and retrival of an address at a fixed storage slot\\n */\\nlibrary AddressStorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored address value\\n */\\n function read(AddressStorage self) internal view returns (address value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value address value to store\\n */\\n function store(AddressStorage self, address value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\\n/**\\n * @title Bytes32StorageLib\\n * @notice Library to manage storage and retrival of a bytes32 at a fixed storage slot\\n */\\nlibrary Bytes32StorageLib {\\n /**\\n * @notice Retrieves the stored value\\n * @param self Storage slot\\n * @return value Stored bytes32 value\\n */\\n function read(Bytes32Storage self) internal view returns (bytes32 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n /**\\n * @notice Stores the value at the specific slot\\n * @param self Storage slot\\n * @param value bytes32 value to store\\n */\\n function store(Bytes32Storage self, bytes32 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe2b8491d1b5aa93f7e059e1a8f156b0ab37fef9ed973be97a64f2eabfc2cc172\",\"license\":\"Apache-2.0\"},\"@equilibria/root/token/types/Token18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"../../number/types/UFixed18.sol\\\";\\n\\n/// @dev Token18\\ntype Token18 is address;\\nusing Token18Lib for Token18 global;\\ntype Token18Storage is bytes32;\\nusing Token18StorageLib for Token18Storage global;\\n\\n/**\\n * @title Token18Lib\\n * @notice Library to manage 18-decimal ERC20s that is compliant with the fixed-decimal types.\\n * @dev Maintains significant gas savings over other Token implementations since no conversion take place\\n */\\nlibrary Token18Lib {\\n using SafeERC20 for IERC20;\\n\\n Token18 public constant ZERO = Token18.wrap(address(0));\\n\\n /**\\n * @notice Returns whether a token is the zero address\\n * @param self Token to check for\\n * @return Whether the token is the zero address\\n */\\n function isZero(Token18 self) internal pure returns (bool) {\\n return Token18.unwrap(self) == Token18.unwrap(ZERO);\\n }\\n\\n /**\\n * @notice Returns whether the two tokens are equal\\n * @param a First token to compare\\n * @param b Second token to compare\\n * @return Whether the two tokens are equal\\n */\\n function eq(Token18 a, Token18 b) internal pure returns (bool) {\\n return Token18.unwrap(a) == Token18.unwrap(b);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend infinite tokens from the caller\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n */\\n function approve(Token18 self, address grantee) internal {\\n IERC20(Token18.unwrap(self)).safeApprove(grantee, type(uint256).max);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend `amount` tokens from the caller\\n * @dev There are important race conditions to be aware of when using this function\\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n * @param amount Amount of tokens to approve to spend\\n */\\n function approve(Token18 self, address grantee, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeApprove(grantee, UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Transfers all held tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to receive the tokens\\n */\\n function push(Token18 self, address recipient) internal {\\n push(self, recipient, balanceOf(self, address(this)));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function push(Token18 self, address recipient, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeTransfer(recipient, UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param amount Amount of tokens to transfer\\n */\\n function pull(Token18 self, address benefactor, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, address(this), UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function pullTo(Token18 self, address benefactor, address recipient, UFixed18 amount) internal {\\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, recipient, UFixed18.unwrap(amount));\\n }\\n\\n /**\\n * @notice Returns the name of the token\\n * @param self Token to check for\\n * @return Token name\\n */\\n function name(Token18 self) internal view returns (string memory) {\\n return IERC20Metadata(Token18.unwrap(self)).name();\\n }\\n\\n /**\\n * @notice Returns the symbol of the token\\n * @param self Token to check for\\n * @return Token symbol\\n */\\n function symbol(Token18 self) internal view returns (string memory) {\\n return IERC20Metadata(Token18.unwrap(self)).symbol();\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of the caller\\n * @param self Token to check for\\n * @return Token balance of the caller\\n */\\n function balanceOf(Token18 self) internal view returns (UFixed18) {\\n return balanceOf(self, address(this));\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of `account`\\n * @param self Token to check for\\n * @param account Account to check\\n * @return Token balance of the account\\n */\\n function balanceOf(Token18 self, address account) internal view returns (UFixed18) {\\n return UFixed18.wrap(IERC20(Token18.unwrap(self)).balanceOf(account));\\n }\\n}\\n\\nlibrary Token18StorageLib {\\n function read(Token18Storage self) internal view returns (Token18 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(Token18Storage self, Token18 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6b12afaece814f0ab186200a4729e93eb685a21d3e9b5a3372ff283a7ad5dc23\",\"license\":\"Apache-2.0\"},\"@equilibria/root/token/types/Token6.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"../../number/types/UFixed18.sol\\\";\\n\\n/// @dev Token6\\ntype Token6 is address;\\nusing Token6Lib for Token6 global;\\ntype Token6Storage is bytes32;\\nusing Token6StorageLib for Token6Storage global;\\n\\n/**\\n * @title Token6Lib\\n * @notice Library to manage 6-decimal ERC20s that is compliant with the fixed-decimal types.\\n * @dev Automatically converts from Base-6 token amounts to Base-18 UFixed18 amounts, with optional rounding\\n */\\nlibrary Token6Lib {\\n using SafeERC20 for IERC20;\\n\\n Token6 public constant ZERO = Token6.wrap(address(0));\\n\\n uint256 private constant OFFSET = 1e12;\\n\\n /**\\n * @notice Returns whether a token is the zero address\\n * @param self Token to check for\\n * @return Whether the token is the zero address\\n */\\n function isZero(Token6 self) internal pure returns (bool) {\\n return Token6.unwrap(self) == Token6.unwrap(ZERO);\\n }\\n\\n /**\\n * @notice Returns whether the two tokens are equal\\n * @param a First token to compare\\n * @param b Second token to compare\\n * @return Whether the two tokens are equal\\n */\\n function eq(Token6 a, Token6 b) internal pure returns (bool) {\\n return Token6.unwrap(a) == Token6.unwrap(b);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend infinite tokens from the caller\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n */\\n function approve(Token6 self, address grantee) internal {\\n IERC20(Token6.unwrap(self)).safeApprove(grantee, type(uint256).max);\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend `amount` tokens from the caller\\n * @dev There are important race conditions to be aware of when using this function\\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n * @param amount Amount of tokens to approve to spend\\n */\\n function approve(Token6 self, address grantee, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Approves `grantee` to spend `amount` tokens from the caller\\n * @dev There are important race conditions to be aware of when using this function\\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n * @param self Token to transfer\\n * @param grantee Address to allow spending\\n * @param amount Amount of tokens to approve to spend\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function approve(Token6 self, address grantee, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Transfers all held tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to receive the tokens\\n */\\n function push(Token6 self, address recipient) internal {\\n push(self, recipient, balanceOf(self, address(this)));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function push(Token6 self, address recipient, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the caller to the `recipient`\\n * @param self Token to transfer\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function push(Token6 self, address recipient, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param amount Amount of tokens to transfer\\n */\\n function pull(Token6 self, address benefactor, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param amount Amount of tokens to transfer\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function pull(Token6 self, address benefactor, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n */\\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, false));\\n }\\n\\n /**\\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n * @dev Reverts if trying to pull Ether\\n * @param self Token to transfer\\n * @param benefactor Address to transfer tokens from\\n * @param recipient Address to transfer tokens to\\n * @param amount Amount of tokens to transfer\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n */\\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount, bool roundUp) internal {\\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, roundUp));\\n }\\n\\n /**\\n * @notice Returns the name of the token\\n * @param self Token to check for\\n * @return Token name\\n */\\n function name(Token6 self) internal view returns (string memory) {\\n return IERC20Metadata(Token6.unwrap(self)).name();\\n }\\n\\n /**\\n * @notice Returns the symbol of the token\\n * @param self Token to check for\\n * @return Token symbol\\n */\\n function symbol(Token6 self) internal view returns (string memory) {\\n return IERC20Metadata(Token6.unwrap(self)).symbol();\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of the caller\\n * @param self Token to check for\\n * @return Token balance of the caller\\n */\\n function balanceOf(Token6 self) internal view returns (UFixed18) {\\n return balanceOf(self, address(this));\\n }\\n\\n /**\\n * @notice Returns the `self` token balance of `account`\\n * @param self Token to check for\\n * @param account Account to check\\n * @return Token balance of the account\\n */\\n function balanceOf(Token6 self, address account) internal view returns (UFixed18) {\\n return fromTokenAmount(IERC20(Token6.unwrap(self)).balanceOf(account));\\n }\\n\\n /**\\n * @notice Converts the unsigned fixed-decimal amount into the token amount according to\\n * it's defined decimals\\n * @dev Provides the ability to \\\"round up\\\" the token amount which is useful in situations where\\n * are swapping one token for another and don't want to give away \\\"free\\\" units due to rounding\\n * errors in the favor of the user.\\n * @param amount Amount to convert\\n * @param roundUp Whether to round decimal token amount up to the next unit\\n * @return Normalized token amount\\n */\\n function toTokenAmount(UFixed18 amount, bool roundUp) private pure returns (uint256) {\\n return roundUp ? Math.ceilDiv(UFixed18.unwrap(amount), OFFSET) : UFixed18.unwrap(amount) / OFFSET;\\n }\\n\\n /**\\n * @notice Converts the token amount into the unsigned fixed-decimal amount according to\\n * it's defined decimals\\n * @param amount Token amount to convert\\n * @return Normalized unsigned fixed-decimal amount\\n */\\n function fromTokenAmount(uint256 amount) private pure returns (UFixed18) {\\n return UFixed18.wrap(amount * OFFSET);\\n }\\n}\\n\\nlibrary Token6StorageLib {\\n function read(Token6Storage self) internal view returns (Token6 value) {\\n assembly {\\n value := sload(self)\\n }\\n }\\n\\n function store(Token6Storage self, Token6 value) internal {\\n assembly {\\n sstore(self, value)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5ec7bee45a0e13f91ab2399472cf11136496073ad470cd70244855e12a7b6e65\",\"license\":\"Apache-2.0\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0xc995bddbca1ae19788db9f8b61e63385edd3fddf89693b612d5abd1a275974d2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\"},\"contracts/interfaces/ICollateral.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"./IController.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface ICollateral {\\n event Deposit(address indexed user, IProduct indexed product, UFixed18 amount);\\n event Withdrawal(address indexed user, IProduct indexed product, UFixed18 amount);\\n event AccountSettle(IProduct indexed product, address indexed account, Fixed18 amount, UFixed18 newShortfall);\\n event ProductSettle(IProduct indexed product, UFixed18 protocolFee, UFixed18 productFee);\\n event Liquidation(address indexed user, IProduct indexed product, address liquidator, UFixed18 fee);\\n event ShortfallResolution(IProduct indexed product, UFixed18 amount);\\n event FeeClaim(address indexed account, UFixed18 amount);\\n\\n error CollateralCantLiquidate(UFixed18 totalMaintenance, UFixed18 totalCollateral);\\n error CollateralInsufficientCollateralError();\\n error CollateralUnderLimitError();\\n error CollateralZeroAddressError();\\n error CollateralAccountLiquidatingError(address account);\\n\\n function token() external view returns (Token18);\\n function fees(address account) external view returns (UFixed18);\\n function initialize(IController controller_) external;\\n function depositTo(address account, IProduct product, UFixed18 amount) external;\\n function withdrawTo(address receiver, IProduct product, UFixed18 amount) external;\\n function withdrawFrom(address account, address receiver, IProduct product, UFixed18 amount) external;\\n function liquidate(address account, IProduct product) external;\\n function settleAccount(address account, Fixed18 amount) external;\\n function settleProduct(UFixed18 amount) external;\\n function collateral(address account, IProduct product) external view returns (UFixed18);\\n function collateral(IProduct product) external view returns (UFixed18);\\n function shortfall(IProduct product) external view returns (UFixed18);\\n function liquidatable(address account, IProduct product) external view returns (bool);\\n function liquidatableNext(address account, IProduct product) external view returns (bool);\\n function resolveShortfall(IProduct product, UFixed18 amount) external;\\n function claimFee() external;\\n}\\n\",\"keccak256\":\"0x6fb67eb5fc3ed4a74522677da3349d75105389369892756a60fcab4c901d352b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IContractPayoffProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\n\\ninterface IContractPayoffProvider {\\n function payoff(Fixed18 price) external view returns (Fixed18 payoff);\\n}\\n\",\"keccak256\":\"0xd73df106d032e976fd959ee6713240e36f54277ce5f215eaec8d5a2c6720a86b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IController.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IIncentivizer.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\nimport \\\"./IMultiInvoker.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\n\\ninterface IController {\\n /// @dev Coordinator of a one or many products\\n struct Coordinator {\\n /// @dev Pending owner of the product, can accept ownership\\n address pendingOwner;\\n\\n /// @dev Owner of the product, allowed to update select parameters\\n address owner;\\n\\n /// @dev Treasury of the product, collects fees\\n address treasury;\\n }\\n\\n event CollateralUpdated(ICollateral newCollateral);\\n event IncentivizerUpdated(IIncentivizer newIncentivizer);\\n event ProductBeaconUpdated(IBeacon newProductBeacon);\\n event MultiInvokerUpdated(IMultiInvoker newMultiInvoker);\\n event ProtocolFeeUpdated(UFixed18 newProtocolFee);\\n event MinFundingFeeUpdated(UFixed18 newMinFundingFee);\\n event LiquidationFeeUpdated(UFixed18 newLiquidationFee);\\n event IncentivizationFeeUpdated(UFixed18 newIncentivizationFee);\\n event MinCollateralUpdated(UFixed18 newMinCollateral);\\n event ProgramsPerProductUpdated(uint256 newProgramsPerProduct);\\n event PauserUpdated(address newPauser);\\n event PausedUpdated(bool newPaused);\\n event CoordinatorPendingOwnerUpdated(uint256 indexed coordinatorId, address newPendingOwner);\\n event CoordinatorOwnerUpdated(uint256 indexed coordinatorId, address newOwner);\\n event CoordinatorTreasuryUpdated(uint256 indexed coordinatorId, address newTreasury);\\n event CoordinatorCreated(uint256 indexed coordinatorId, address owner);\\n event ProductCreated(IProduct indexed product, IProduct.ProductInfo productInfo);\\n\\n error ControllerNoZeroCoordinatorError();\\n error ControllerNotPauserError();\\n error ControllerNotOwnerError(uint256 controllerId);\\n error ControllerNotPendingOwnerError(uint256 controllerId);\\n error ControllerInvalidProtocolFeeError();\\n error ControllerInvalidMinFundingFeeError();\\n error ControllerInvalidLiquidationFeeError();\\n error ControllerInvalidIncentivizationFeeError();\\n error ControllerNotContractAddressError();\\n\\n function collateral() external view returns (ICollateral);\\n function incentivizer() external view returns (IIncentivizer);\\n function productBeacon() external view returns (IBeacon);\\n function multiInvoker() external view returns (IMultiInvoker);\\n function coordinators(uint256 collateralId) external view returns (Coordinator memory);\\n function coordinatorFor(IProduct product) external view returns (uint256);\\n function protocolFee() external view returns (UFixed18);\\n function minFundingFee() external view returns (UFixed18);\\n function liquidationFee() external view returns (UFixed18);\\n function incentivizationFee() external view returns (UFixed18);\\n function minCollateral() external view returns (UFixed18);\\n function programsPerProduct() external view returns (uint256);\\n function pauser() external view returns (address);\\n function paused() external view returns (bool);\\n function initialize(ICollateral collateral_, IIncentivizer incentivizer_, IBeacon productBeacon_) external;\\n function createCoordinator() external returns (uint256);\\n function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external;\\n function acceptCoordinatorOwner(uint256 coordinatorId) external;\\n function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external;\\n function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo) external returns (IProduct);\\n function updateCollateral(ICollateral newCollateral) external;\\n function updateIncentivizer(IIncentivizer newIncentivizer) external;\\n function updateProductBeacon(IBeacon newProductBeacon) external;\\n function updateMultiInvoker(IMultiInvoker newMultiInvoker) external;\\n function updateProtocolFee(UFixed18 newProtocolFee) external;\\n function updateMinFundingFee(UFixed18 newMinFundingFee) external;\\n function updateLiquidationFee(UFixed18 newLiquidationFee) external;\\n function updateIncentivizationFee(UFixed18 newIncentivizationFee) external;\\n function updateMinCollateral(UFixed18 newMinCollateral) external;\\n function updateProgramsPerProduct(uint256 newProductsPerProduct) external;\\n function updatePauser(address newPauser) external;\\n function updatePaused(bool newPaused) external;\\n function isProduct(IProduct product) external view returns (bool);\\n function owner() external view returns (address);\\n function owner(uint256 coordinatorId) external view returns (address);\\n function owner(IProduct product) external view returns (address);\\n function treasury() external view returns (address);\\n function treasury(uint256 coordinatorId) external view returns (address);\\n function treasury(IProduct product) external view returns (address);\\n}\\n\",\"keccak256\":\"0xb6798b45b76edb91f6e56380eeeacdcfb37bbeb620a2d9c3e9993c39675bbd48\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IIncentivizer.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./types/ProgramInfo.sol\\\";\\nimport \\\"./IController.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IIncentivizer {\\n event ProgramCreated(IProduct indexed product, uint256 indexed programId, ProgramInfo programInfo, UFixed18 programFeeAmount);\\n event ProgramStarted(IProduct indexed product, uint256 indexed programId, uint256 version);\\n event ProgramComplete(IProduct indexed product, uint256 indexed programId, uint256 version);\\n event Claim(IProduct indexed product, address indexed account, uint256 indexed programId, UFixed18 amount);\\n event FeeClaim(Token18 indexed token, UFixed18 amount);\\n\\n error IncentivizerNotAllowedError(IProduct product);\\n error IncentivizerTooManyProgramsError();\\n error IncentivizerNotProgramOwnerError(IProduct product, uint256 programId);\\n error IncentivizerInvalidProgramError(IProduct product, uint256 programId);\\n error IncentivizerBatchClaimArgumentMismatchError();\\n\\n function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory);\\n function fees(Token18 token) external view returns (UFixed18);\\n function initialize(IController controller_) external;\\n function create(IProduct product, ProgramInfo calldata info) external returns (uint256);\\n function complete(IProduct product, uint256 programId) external;\\n function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external;\\n function syncAccount(address account, IOracleProvider.OracleVersion memory currentOracleVersion) external;\\n function claim(IProduct product, uint256[] calldata programIds) external;\\n function claimFor(address account, IProduct product, uint256[] calldata programIds) external;\\n function claim(IProduct[] calldata products, uint256[][] calldata programIds) external;\\n function claimFee(Token18[] calldata tokens) external;\\n function active(IProduct product) external view returns (uint256);\\n function count(IProduct product) external view returns (uint256);\\n function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18);\\n function available(IProduct product, uint256 programId) external view returns (UFixed18);\\n function versionStarted(IProduct product, uint256 programId) external view returns (uint256);\\n function versionComplete(IProduct product, uint256 programId) external view returns (uint256);\\n function owner(IProduct product, uint256 programId) external view returns (address);\\n function treasury(IProduct product, uint256 programId) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd9d65d1190d830c8b797829f94194db86bb712e51f404e8c3e2c9b1df5645649\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IMultiInvoker.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\\\";\\n\\nimport \\\"./IController.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IPerennialVault {\\n event Deposit(address indexed sender, address indexed account, uint256 version, UFixed18 assets);\\n event Redemption(address indexed sender, address indexed account, uint256 version, UFixed18 shares);\\n event Claim(address indexed sender, address indexed account, UFixed18 assets);\\n\\n function deposit(UFixed18 assets, address account) external;\\n function redeem(UFixed18 shares, address account) external;\\n function claim(address account) external;\\n}\\n\\ninterface IMultiInvoker {\\n /// @dev Core protocol actions that can be composed\\n enum PerennialAction {\\n NO_OP,\\n DEPOSIT,\\n WITHDRAW,\\n OPEN_TAKE,\\n CLOSE_TAKE,\\n OPEN_MAKE,\\n CLOSE_MAKE,\\n CLAIM,\\n WRAP,\\n UNWRAP,\\n WRAP_AND_DEPOSIT,\\n WITHDRAW_AND_UNWRAP,\\n VAULT_DEPOSIT,\\n VAULT_REDEEM,\\n VAULT_CLAIM,\\n VAULT_WRAP_AND_DEPOSIT\\n }\\n\\n /// @dev Struct for action invocation\\n struct Invocation {\\n PerennialAction action;\\n bytes args;\\n }\\n\\n function initialize() external;\\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\\n function batcher() external view returns (IBatcher);\\n function controller() external view returns (IController);\\n function collateral() external view returns (ICollateral);\\n function reserve() external view returns (IEmptySetReserve);\\n function invoke(Invocation[] calldata invocations) external;\\n}\\n\",\"keccak256\":\"0xf54645562fc10f688ac76328858ed1299e8f30eb1be4f4196f016f9851c6c3c9\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IMultiInvokerRollup.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./IMultiInvoker.sol\\\";\\n\\ninterface IMultiInvokerRollup is IMultiInvoker {\\n event AddressAddedToCache(address indexed addr, uint256 nonce);\\n /// @dev reverts when calldata has an issue. causes: length of bytes in a uint > || cache index empty\\n error MultiInvokerRollupInvalidCalldataError();\\n\\n function addressCache(uint256 nonce) external view returns(address);\\n function addressLookup(address addr) external view returns(uint256 nonce);\\n}\\n\",\"keccak256\":\"0x4d7dcf62379f35f0e78e8eb4d2ecf9daeed5d32097dd29032c3140e88ef062f9\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IParamProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\\\";\\nimport \\\"./types/PendingFeeUpdates.sol\\\";\\n\\ninterface IParamProvider {\\n event MaintenanceUpdated(UFixed18 newMaintenance, uint256 version);\\n event FundingFeeUpdated(UFixed18 newFundingFee, uint256 version);\\n event MakerFeeUpdated(UFixed18 newMakerFee, uint256 version);\\n event PendingMakerFeeUpdated(UFixed18 newMakerFee);\\n event TakerFeeUpdated(UFixed18 newTakerFee, uint256 version);\\n event PendingTakerFeeUpdated(UFixed18 newTakerFee);\\n event PositionFeeUpdated(UFixed18 newPositionFee, uint256 version);\\n event PendingPositionFeeUpdated(UFixed18 newPositionFee);\\n event MakerLimitUpdated(UFixed18 newMakerLimit, uint256 version);\\n event JumpRateUtilizationCurveUpdated(\\n JumpRateUtilizationCurve,\\n uint256 version\\n );\\n\\n error ParamProviderInvalidParamValue();\\n\\n function maintenance() external view returns (UFixed18);\\n function updateMaintenance(UFixed18 newMaintenance) external;\\n function fundingFee() external view returns (UFixed18);\\n function updateFundingFee(UFixed18 newFundingFee) external;\\n function makerFee() external view returns (UFixed18);\\n function updateMakerFee(UFixed18 newMakerFee) external;\\n function takerFee() external view returns (UFixed18);\\n function updateTakerFee(UFixed18 newTakerFee) external;\\n function positionFee() external view returns (UFixed18);\\n function updatePositionFee(UFixed18 newPositionFee) external;\\n function makerLimit() external view returns (UFixed18);\\n function updateMakerLimit(UFixed18 newMakerLimit) external;\\n function utilizationCurve() external view returns (JumpRateUtilizationCurve memory);\\n function updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) external;\\n function pendingFeeUpdates() external view returns (PendingFeeUpdates memory);\\n}\\n\",\"keccak256\":\"0x21584bd07296eb4e8bd6076fd20afad320e781c19c60b479c9340c69b0f37517\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IPayoffProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\n\\ninterface IPayoffProvider {\\n event OracleUpdated(address newOracle, uint256 oracleVersion);\\n\\n error PayoffProviderInvalidOracle();\\n error PayoffProviderInvalidPayoffDefinitionError();\\n\\n function oracle() external view returns (IOracleProvider);\\n function payoffDefinition() external view returns (PayoffDefinition memory);\\n function currentVersion() external view returns (IOracleProvider.OracleVersion memory);\\n function atVersion(uint256 oracleVersion) external view returns (IOracleProvider.OracleVersion memory);\\n}\\n\",\"keccak256\":\"0x803d22f7513c2c5186f77f6bc7cc34673ed762e40f106f9aef512eb9b57018af\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IProduct.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\\\";\\nimport \\\"./IPayoffProvider.sol\\\";\\nimport \\\"./IParamProvider.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\nimport \\\"./types/Position.sol\\\";\\nimport \\\"./types/PrePosition.sol\\\";\\nimport \\\"./types/Accumulator.sol\\\";\\n\\ninterface IProduct is IPayoffProvider, IParamProvider {\\n /// @dev Product Creation parameters\\n struct ProductInfo {\\n /// @dev name of the product\\n string name;\\n\\n /// @dev symbol of the product\\n string symbol;\\n\\n /// @dev product payoff definition\\n PayoffDefinition payoffDefinition;\\n\\n /// @dev oracle address\\n IOracleProvider oracle;\\n\\n /// @dev product maintenance ratio\\n UFixed18 maintenance;\\n\\n /// @dev product funding fee\\n UFixed18 fundingFee;\\n\\n /// @dev product maker fee\\n UFixed18 makerFee;\\n\\n /// @dev product taker fee\\n UFixed18 takerFee;\\n\\n /// @dev product position fee share\\n UFixed18 positionFee;\\n\\n /// @dev product maker limit\\n UFixed18 makerLimit;\\n\\n /// @dev utulization curve definition\\n JumpRateUtilizationCurve utilizationCurve;\\n }\\n\\n event Settle(uint256 preVersion, uint256 toVersion);\\n event AccountSettle(address indexed account, uint256 preVersion, uint256 toVersion);\\n event MakeOpened(address indexed account, uint256 version, UFixed18 amount);\\n event TakeOpened(address indexed account, uint256 version, UFixed18 amount);\\n event MakeClosed(address indexed account, uint256 version, UFixed18 amount);\\n event TakeClosed(address indexed account, uint256 version, UFixed18 amount);\\n event ClosedUpdated(bool indexed newClosed, uint256 version);\\n\\n error ProductInsufficientLiquidityError(UFixed18 socializationFactor);\\n error ProductDoubleSidedError();\\n error ProductOverClosedError();\\n error ProductInsufficientCollateralError();\\n error ProductInLiquidationError();\\n error ProductMakerOverLimitError();\\n error ProductOracleBootstrappingError();\\n error ProductClosedError();\\n\\n function name() external view returns (string memory);\\n function symbol() external view returns (string memory);\\n function initialize(ProductInfo calldata productInfo_) external;\\n function settle() external;\\n function settleAccount(address account) external;\\n function openTake(UFixed18 amount) external;\\n function openTakeFor(address account, UFixed18 amount) external;\\n function closeTake(UFixed18 amount) external;\\n function closeTakeFor(address account, UFixed18 amount) external;\\n function openMake(UFixed18 amount) external;\\n function openMakeFor(address account, UFixed18 amount) external;\\n function closeMake(UFixed18 amount) external;\\n function closeMakeFor(address account, UFixed18 amount) external;\\n function closeAll(address account) external;\\n function maintenance(address account) external view returns (UFixed18);\\n function maintenanceNext(address account) external view returns (UFixed18);\\n function isClosed(address account) external view returns (bool);\\n function isLiquidating(address account) external view returns (bool);\\n function position(address account) external view returns (Position memory);\\n function pre(address account) external view returns (PrePosition memory);\\n function latestVersion() external view returns (uint256);\\n function positionAtVersion(uint256 oracleVersion) external view returns (Position memory);\\n function pre() external view returns (PrePosition memory);\\n function valueAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\\n function shareAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\\n function latestVersion(address account) external view returns (uint256);\\n function rate(Position memory position) external view returns (Fixed18);\\n function closed() external view returns (bool);\\n function updateClosed(bool newClosed) external;\\n function updateOracle(IOracleProvider newOracle) external;\\n}\\n\",\"keccak256\":\"0x8e53ea97d8d59519adcbc2aa3600b5e51de1d59efec485a88eca8b574a35a00f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/Accumulator.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"./PackedAccumulator.sol\\\";\\n\\n/// @dev Accumulator type\\nstruct Accumulator {\\n /// @dev maker accumulator per share\\n Fixed18 maker;\\n /// @dev taker accumulator per share\\n Fixed18 taker;\\n}\\nusing AccumulatorLib for Accumulator global;\\n\\n/**\\n * @title AccountAccumulatorLib\\n * @notice Library that surfaces math operations for the Accumulator type.\\n * @dev Accumulators track the cumulative change in position value over time for the maker and taker positions\\n * respectively. Account-level accumulators can then use two of these values `a` and `a'` to compute the\\n * change in position value since last sync. This change in value is then used to compute P&L and fees.\\n */\\nlibrary AccumulatorLib {\\n /**\\n * @notice Creates a packed accumulator from an accumulator\\n * @param self an accumulator\\n * @return New packed accumulator\\n */\\n function pack(Accumulator memory self) internal pure returns (PackedAccumulator memory) {\\n return PackedAccumulator({maker: self.maker.pack(), taker: self.taker.pack()});\\n }\\n\\n /**\\n * @notice Adds two accumulators together\\n * @param a The first accumulator to sum\\n * @param b The second accumulator to sum\\n * @return The resulting summed accumulator\\n */\\n function add(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\\n }\\n\\n /**\\n * @notice Subtracts accumulator `b` from `a`\\n * @param a The accumulator to subtract from\\n * @param b The accumulator to subtract\\n * @return The resulting subtracted accumulator\\n */\\n function sub(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\\n }\\n\\n /**\\n * @notice Multiplies two accumulators together\\n * @param a The first accumulator to multiply\\n * @param b The second accumulator to multiply\\n * @return The resulting multiplied accumulator\\n */\\n function mul(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: a.maker.mul(b.maker), taker: a.taker.mul(b.taker)});\\n }\\n\\n /**\\n * @notice Sums the maker and taker together from a single accumulator\\n * @param self The struct to operate on\\n * @return The sum of its maker and taker\\n */\\n function sum(Accumulator memory self) internal pure returns (Fixed18) {\\n return self.maker.add(self.taker);\\n }\\n}\\n\",\"keccak256\":\"0x7ccd0a72aa593cefb9f4337cf312799f357b82fcb3f0379de0dc503d1cb7e387\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PackedAccumulator.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/PackedFixed18.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\n\\n/// @dev PackedAccumulator type\\nstruct PackedAccumulator {\\n /// @dev maker accumulator per share\\n PackedFixed18 maker;\\n /// @dev taker accumulator per share\\n PackedFixed18 taker;\\n}\\nusing PackedAccumulatorLib for PackedAccumulator global;\\n\\n/**\\n * @title PackedAccumulatorLib\\n * @dev A packed version of the Accumulator which takes up a single storage slot using `PackedFixed18` values.\\n * @notice Library for the packed Accumulator type.\\n */\\nlibrary PackedAccumulatorLib {\\n /**\\n * @notice Creates an accumulator from a packed accumulator\\n * @param self packed accumulator\\n * @return New accumulator\\n */\\n function unpack(PackedAccumulator memory self) internal pure returns (Accumulator memory) {\\n return Accumulator({maker: self.maker.unpack(), taker: self.taker.unpack()});\\n }\\n}\\n\",\"keccak256\":\"0xd83f2822d4f6c818087a232b54007730992c34ff77377fc307a282f886e7cf65\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PackedPosition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/PackedUFixed18.sol\\\";\\nimport \\\"./Position.sol\\\";\\n\\n/// @dev PackedPosition type\\nstruct PackedPosition {\\n /// @dev Quantity of the maker position\\n PackedUFixed18 maker;\\n /// @dev Quantity of the taker position\\n PackedUFixed18 taker;\\n}\\nusing PackedPositionLib for PackedPosition global;\\n\\n/**\\n * @title PackedPositionLib\\n * @dev A packed version of the Position which takes up a single storage slot using `PackedFixed18` values.\\n * @notice Library for the packed Position type.\\n */\\nlibrary PackedPositionLib {\\n /**\\n * @notice Creates an position from a packed position\\n * @param self packed position\\n * @return New position\\n */\\n function unpack(PackedPosition memory self) internal pure returns (Position memory) {\\n return Position({maker: self.maker.unpack(), taker: self.taker.unpack()});\\n }\\n}\\n\",\"keccak256\":\"0x04968e6794f6244cb3415cea111d640273a81faea957872988d0cb580f45df1e\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PayoffDefinition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../../interfaces/IContractPayoffProvider.sol\\\";\\n\\n/// @dev PayoffDefinition tyoe\\nstruct PayoffDefinition {\\n PayoffDefinitionLib.PayoffType payoffType;\\n PayoffDefinitionLib.PayoffDirection payoffDirection;\\n bytes30 data;\\n}\\nusing PayoffDefinitionLib for PayoffDefinition global;\\ntype PayoffDefinitionStorage is bytes32;\\nusing PayoffDefinitionStorageLib for PayoffDefinitionStorage global;\\n\\n/**\\n * @title PayoffDefinitionLib\\n * @dev Library that surfaces logic for PayoffDefinition type functionality\\n * @notice Library for the PayoffDefinition type. Performs validity and price transformation\\n based on the payoff definition type.\\n */\\nlibrary PayoffDefinitionLib {\\n using Address for address;\\n\\n error PayoffDefinitionUnsupportedTransform(PayoffType payoffType, PayoffDirection payoffDirection);\\n error PayoffDefinitionNotContract(PayoffType payoffType, bytes30 data);\\n\\n /// @dev Payoff function type enum\\n enum PayoffType { PASSTHROUGH, CONTRACT }\\n enum PayoffDirection { LONG, SHORT }\\n\\n /**\\n * @notice Checks validity of the payoff definition\\n * @param self a payoff definition\\n * @return Whether the payoff definition is valid for it's given type\\n */\\n function valid(PayoffDefinition memory self) internal view returns (bool) {\\n if (self.payoffType == PayoffType.CONTRACT) return address(_providerContract(self)).isContract();\\n\\n // All other payoff types should have no data\\n return uint(bytes32(self.data)) == 0;\\n }\\n\\n /**\\n * @notice Transforms a price based on the payoff definition\\n * @param self a payoff definition\\n * @param price raw oracle price\\n * @return Price transformed by the payoff definition function\\n */\\n function transform(\\n PayoffDefinition memory self,\\n Fixed18 price\\n ) internal view returns (Fixed18) {\\n PayoffType payoffType = self.payoffType;\\n PayoffDirection payoffDirection = self.payoffDirection;\\n Fixed18 transformedPrice;\\n\\n // First get the price depending on the type\\n if (payoffType == PayoffType.PASSTHROUGH) transformedPrice = price;\\n else if (payoffType == PayoffType.CONTRACT) transformedPrice = _payoffFromContract(self, price);\\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\\n\\n // Then transform it depending on the direction flag\\n if (self.payoffDirection == PayoffDirection.LONG) return transformedPrice;\\n else if (self.payoffDirection == PayoffDirection.SHORT) return transformedPrice.mul(Fixed18Lib.NEG_ONE);\\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\\n }\\n\\n /**\\n * @notice Parses the data field into an address\\n * @dev Reverts if payoffType is not CONTRACT\\n * @param self a payoff definition\\n * @return IContractPayoffProvider address\\n */\\n function _providerContract(\\n PayoffDefinition memory self\\n ) private pure returns (IContractPayoffProvider) {\\n if (self.payoffType != PayoffType.CONTRACT) revert PayoffDefinitionNotContract(self.payoffType, self.data);\\n // Shift to pull the last 20 bytes, then cast to an address\\n return IContractPayoffProvider(address(bytes20(self.data << 80)));\\n }\\n\\n /**\\n * @notice Performs a price transformation by calling the underlying payoff contract\\n * @param self a payoff definition\\n * @param price raw oracle price\\n * @return Price transformed by the payoff definition function on the contract\\n */\\n function _payoffFromContract(\\n PayoffDefinition memory self,\\n Fixed18 price\\n ) private view returns (Fixed18) {\\n bytes memory ret = address(_providerContract(self)).functionStaticCall(\\n abi.encodeCall(IContractPayoffProvider.payoff, price)\\n );\\n return Fixed18.wrap(abi.decode(ret, (int256)));\\n }\\n}\\n\\n/**\\n * @title PayoffDefinitionStorageLib\\n * @notice Library that surfaces storage read and writes for the PayoffDefinition type\\n */\\nlibrary PayoffDefinitionStorageLib {\\n function read(PayoffDefinitionStorage self) internal view returns (PayoffDefinition memory) {\\n return _storagePointer(self);\\n }\\n\\n function store(PayoffDefinitionStorage self, PayoffDefinition memory value) internal {\\n PayoffDefinition storage storagePointer = _storagePointer(self);\\n\\n storagePointer.payoffType = value.payoffType;\\n storagePointer.payoffDirection = value.payoffDirection;\\n storagePointer.data = value.data;\\n }\\n\\n function _storagePointer(\\n PayoffDefinitionStorage self\\n ) private pure returns (PayoffDefinition storage pointer) {\\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\\n }\\n}\\n\",\"keccak256\":\"0x99f9b5d5facba16885a375beac2a05129e7b23a8cceee048a7affd7f12a18a8f\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PendingFeeUpdates.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\n/// @dev PendingFeeUpdates type. Fees can be between 0 and 1 ** 10^18, so uint64 is sufficient\\nstruct PendingFeeUpdates {\\n bool makerFeeUpdated;\\n uint64 pendingMakerFee;\\n bool takerFeeUpdated;\\n uint64 pendingTakerFee;\\n bool positionFeeUpdated;\\n uint64 pendingPositionFee;\\n}\\nusing PendingFeeUpdatesLib for PendingFeeUpdates global;\\ntype PendingFeeUpdatesStorage is bytes32;\\nusing PendingFeeUpdatesStorageLib for PendingFeeUpdatesStorage global;\\n\\n/**\\n * @title PendingFeeUpdatesLib\\n * @dev Library that surfaces convenience functions for the PendingFeeUpdates type\\n * @notice Library for the PendingFeeUpdates type. Allows for setting and reading fee updates and clearing state\\n */\\nlibrary PendingFeeUpdatesLib {\\n error PendingFeeUpdatesUnsupportedValue(UFixed18 value);\\n\\n /**\\n * @notice Updates the pending maker fee to `newMakerFee` and sets the `makerFeeUpdated` flag\\n * @dev Reverts if `newMakerFee` is invalid\\n * @param self PendingFeeUpdates struct\\n * @param newMakerFee new maker fee value\\n */\\n function updateMakerFee(PendingFeeUpdates memory self, UFixed18 newMakerFee) internal pure {\\n if (UFixed18.unwrap(newMakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newMakerFee);\\n self.pendingMakerFee = uint64(UFixed18.unwrap(newMakerFee));\\n self.makerFeeUpdated = true;\\n }\\n\\n /// @dev Returns the UFixed18-wrapped pending maker fee\\n function makerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(self.pendingMakerFee));\\n }\\n\\n /**\\n * @notice Updates the pending taker fee to `newTakerFee` and sets the `takerFeeUpdated` flag\\n * @dev Reverts if `newTakerFee` is invalid\\n * @param self PendingFeeUpdates struct\\n * @param newTakerFee new taker fee value\\n */\\n function updateTakerFee(PendingFeeUpdates memory self, UFixed18 newTakerFee) internal pure {\\n if (UFixed18.unwrap(newTakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newTakerFee);\\n self.pendingTakerFee = uint64(UFixed18.unwrap(newTakerFee));\\n self.takerFeeUpdated = true;\\n }\\n\\n /// @dev Returns the UFixed18-wrapped pending taker fee\\n function takerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(self.pendingTakerFee));\\n }\\n\\n /**\\n * @notice Updates the pending position fee to `newPositionFee` and sets the `positionFeeUpdated` flag\\n * @dev Reverts if `newPositionFee` is invalid\\n * @param self PendingFeeUpdates struct\\n * @param newPositionFee new position fee value\\n */\\n function updatePositionFee(PendingFeeUpdates memory self, UFixed18 newPositionFee) internal pure {\\n if (UFixed18.unwrap(newPositionFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newPositionFee);\\n self.pendingPositionFee = uint64(UFixed18.unwrap(newPositionFee));\\n self.positionFeeUpdated = true;\\n }\\n\\n /// @dev Returns the UFixed18-wrapped pending position fee\\n function positionFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n return UFixed18.wrap(uint256(self.pendingPositionFee));\\n }\\n\\n /// @dev Returns true if any of the updated flags are true\\n function hasUpdates(PendingFeeUpdates memory self) internal pure returns (bool) {\\n return self.makerFeeUpdated || self.takerFeeUpdated || self.positionFeeUpdated;\\n }\\n\\n /// @dev Resets all struct values to defaults\\n function clear(PendingFeeUpdates memory self) internal pure {\\n self.makerFeeUpdated = false;\\n self.pendingMakerFee = 0;\\n self.takerFeeUpdated = false;\\n self.pendingTakerFee = 0;\\n self.positionFeeUpdated = false;\\n self.pendingPositionFee = 0;\\n }\\n}\\n\\n/**\\n * @title PendingFeeUpdatesStorageLib\\n * @notice Library that surfaces storage read and writes for the PendingFeeUpdates type\\n */\\nlibrary PendingFeeUpdatesStorageLib {\\n struct PendingFeeUpdatesStoragePointer {\\n PendingFeeUpdates value;\\n }\\n\\n function read(PendingFeeUpdatesStorage self) internal view returns (PendingFeeUpdates memory) {\\n return _storagePointer(self).value;\\n }\\n\\n function store(PendingFeeUpdatesStorage self, PendingFeeUpdates memory value) internal {\\n _storagePointer(self).value = value;\\n }\\n\\n function _storagePointer(\\n PendingFeeUpdatesStorage self\\n ) private pure returns (PendingFeeUpdatesStoragePointer storage pointer) {\\n /// @solidity memory-safe-assembly\\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\\n }\\n}\\n\",\"keccak256\":\"0xd98c681bdd6e1808e311615b3c4ac3b557ce5ec461f7b1cc645a51590eaf6f93\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/Position.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\nimport \\\"./PrePosition.sol\\\";\\nimport \\\"./PackedPosition.sol\\\";\\n\\n/// @dev Position type\\nstruct Position {\\n /// @dev Quantity of the maker position\\n UFixed18 maker;\\n /// @dev Quantity of the taker position\\n UFixed18 taker;\\n}\\nusing PositionLib for Position global;\\n\\n/**\\n * @title PositionLib\\n * @notice Library that surfaces math and settlement computations for the Position type.\\n * @dev Positions track the current quantity of the account's maker and taker positions respectively\\n * denominated as a unit of the product's payoff function.\\n */\\nlibrary PositionLib {\\n /**\\n * @notice Creates a packed position from an position\\n * @param self A position\\n * @return New packed position\\n */\\n function pack(Position memory self) internal pure returns (PackedPosition memory) {\\n return PackedPosition({maker: self.maker.pack(), taker: self.taker.pack()});\\n }\\n\\n /**\\n * @notice Returns whether the position is fully empty\\n * @param self A position\\n * @return Whether the position is empty\\n */\\n function isEmpty(Position memory self) internal pure returns (bool) {\\n return self.maker.isZero() && self.taker.isZero();\\n }\\n\\n /**\\n * @notice Adds position `a` and `b` together, returning the result\\n * @param a The first position to sum\\n * @param b The second position to sum\\n * @return Resulting summed position\\n */\\n function add(Position memory a, Position memory b) internal pure returns (Position memory) {\\n return Position({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\\n }\\n\\n /**\\n * @notice Subtracts position `b` from `a`, returning the result\\n * @param a The position to subtract from\\n * @param b The position to subtract\\n * @return Resulting subtracted position\\n */\\n function sub(Position memory a, Position memory b) internal pure returns (Position memory) {\\n return Position({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\\n }\\n\\n /**\\n * @notice Multiplies position `self` by accumulator `accumulator` and returns the resulting accumulator\\n * @param self The Position to operate on\\n * @param accumulator The accumulator to multiply by\\n * @return Resulting multiplied accumulator\\n */\\n function mul(Position memory self, Accumulator memory accumulator) internal pure returns (Accumulator memory) {\\n return Accumulator({\\n maker: Fixed18Lib.from(self.maker).mul(accumulator.maker),\\n taker: Fixed18Lib.from(self.taker).mul(accumulator.taker)\\n });\\n }\\n\\n /**\\n * @notice Scales position `self` by fixed-decimal `scale` and returns the resulting position\\n * @param self The Position to operate on\\n * @param scale The Fixed-decimal to scale by\\n * @return Resulting scaled position\\n */\\n function mul(Position memory self, UFixed18 scale) internal pure returns (Position memory) {\\n return Position({maker: self.maker.mul(scale), taker: self.taker.mul(scale)});\\n }\\n\\n /**\\n * @notice Divides position `self` by `b` and returns the resulting accumulator\\n * @param self The Position to operate on\\n * @param b The number to divide by\\n * @return Resulting divided accumulator\\n */\\n function div(Position memory self, uint256 b) internal pure returns (Accumulator memory) {\\n return Accumulator({\\n maker: Fixed18Lib.from(self.maker).div(Fixed18Lib.from(UFixed18Lib.from(b))),\\n taker: Fixed18Lib.from(self.taker).div(Fixed18Lib.from(UFixed18Lib.from(b)))\\n });\\n }\\n\\n /**\\n * @notice Returns the maximum of `self`'s maker and taker values\\n * @param self The struct to operate on\\n * @return Resulting maximum value\\n */\\n function max(Position memory self) internal pure returns (UFixed18) {\\n return UFixed18Lib.max(self.maker, self.taker);\\n }\\n\\n /**\\n * @notice Sums the maker and taker together from a single position\\n * @param self The struct to operate on\\n * @return The sum of its maker and taker\\n */\\n function sum(Position memory self) internal pure returns (UFixed18) {\\n return self.maker.add(self.taker);\\n }\\n\\n /**\\n * @notice Computes the next position after the pending-settlement position delta is included\\n * @param self The current Position\\n * @param pre The pending-settlement position delta\\n * @return Next Position\\n */\\n function next(Position memory self, PrePosition memory pre) internal pure returns (Position memory) {\\n return sub(add(self, pre.openPosition), pre.closePosition);\\n }\\n\\n /**\\n * @notice Returns the settled position at oracle version `toOracleVersion`\\n * @dev Checks if a new position is ready to be settled based on the provided `toOracleVersion`\\n * and `pre` and returns accordingly\\n * @param self The current Position\\n * @param pre The pending-settlement position delta\\n * @param toOracleVersion The oracle version to settle to\\n * @return Settled position at oracle version\\n * @return Whether a new position was settled\\n */\\n function settled(\\n Position memory self,\\n PrePosition memory pre,\\n IOracleProvider.OracleVersion memory toOracleVersion\\n ) internal pure returns (Position memory, bool) {\\n return pre.canSettle(toOracleVersion) ? (next(self, pre), true) : (self, false);\\n }\\n\\n /**\\n * @notice Returns the socialization factor for the current position\\n * @dev Socialization account for the case where `taker` > `maker` temporarily due to a liquidation\\n * on the maker side. This dampens the taker's exposure pro-rata to ensure that the maker side\\n * is never exposed over 1 x short.\\n * @param self The Position to operate on\\n * @return Socialization factor\\n */\\n function socializationFactor(Position memory self) internal pure returns (UFixed18) {\\n return self.taker.isZero() ? UFixed18Lib.ONE : UFixed18Lib.min(UFixed18Lib.ONE, self.maker.div(self.taker));\\n }\\n}\\n\",\"keccak256\":\"0x367918730021f3d6b7035f40c53b00b4316eb5e7fa409ed6285ba6d49971aab1\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PrePosition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\n\\n/// @dev PrePosition type\\nstruct PrePosition {\\n /// @dev Oracle version at which the new position delta was recorded\\n uint256 oracleVersion;\\n\\n /// @dev Size of position to open at oracle version\\n Position openPosition;\\n\\n /// @dev Size of position to close at oracle version\\n Position closePosition;\\n}\\nusing PrePositionLib for PrePosition global;\\n\\n/**\\n * @title PrePositionLib\\n * @notice Library that manages a pre-settlement position delta.\\n * @dev PrePositions track the currently awaiting-settlement deltas to a settled Position. These are\\n * Primarily necessary to introduce lag into the settlement system such that oracle lag cannot be\\n * gamed to a user's advantage. When a user opens or closes a new position, it sits as a PrePosition\\n * for one oracle version until it's settle into the Position, making it then effective. PrePositions\\n * are automatically settled at the correct oracle version even if a flywheel call doesn't happen until\\n * several version into the future by using the historical version lookups in the corresponding \\\"Versioned\\\"\\n * global state types.\\n */\\nlibrary PrePositionLib {\\n /**\\n * @notice Returns whether there is no pending-settlement position delta\\n * @param self The struct to operate on\\n * @return Whether the pending-settlement position delta is empty\\n */\\n function isEmpty(PrePosition memory self) internal pure returns (bool) {\\n return self.openPosition.isEmpty() && self.closePosition.isEmpty();\\n }\\n\\n /**\\n * @notice Increments the maker side of the open position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The position amount to open\\n */\\n function openMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.openPosition.maker = self.openPosition.maker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Increments the maker side of the close position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The maker position amount to close\\n */\\n function closeMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.closePosition.maker = self.closePosition.maker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Increments the taker side of the open position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The taker position amount to open\\n */\\n function openTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.openPosition.taker = self.openPosition.taker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Increments the taker side of the close position delta\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @param amount The taker position amount to close\\n */\\n function closeTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n self.closePosition.taker = self.closePosition.taker.add(amount);\\n self.oracleVersion = currentVersion;\\n }\\n\\n /**\\n * @notice Returns whether the the pending position delta can be settled at version `toOracleVersion`\\n * @dev Pending-settlement positions deltas can be settled (1) oracle version after they are recorded\\n * @param self The struct to operate on\\n * @param toOracleVersion The potential oracle version to settle\\n * @return Whether the position delta can be settled\\n */\\n function canSettle(\\n PrePosition memory self,\\n IOracleProvider.OracleVersion memory toOracleVersion\\n ) internal pure returns (bool) {\\n return self.oracleVersion != 0 && toOracleVersion.version > self.oracleVersion;\\n }\\n\\n /**\\n * @notice Computes the fee incurred for opening or closing the pending-settlement position\\n * @dev Must be called from a valid product to get the proper fee amounts\\n * @param self The struct to operate on\\n * @param latestOracleVersion The oracle version at which position was modified\\n * @return The maker / taker fee incurred\\n */\\n function computeFee(\\n PrePosition memory self,\\n IOracleProvider.OracleVersion memory latestOracleVersion\\n ) internal view returns (Position memory) {\\n Position memory positionDelta = self.openPosition.add(self.closePosition);\\n\\n (UFixed18 makerNotional, UFixed18 takerNotional) = (\\n Fixed18Lib.from(positionDelta.maker).mul(latestOracleVersion.price).abs(),\\n Fixed18Lib.from(positionDelta.taker).mul(latestOracleVersion.price).abs()\\n );\\n\\n IProduct product = IProduct(address(this));\\n return Position(makerNotional.mul(product.makerFee()), takerNotional.mul(product.takerFee()));\\n }\\n\\n /**\\n * @notice Computes the next oracle version to settle\\n * @dev - If there is no pending-settlement position delta, returns the current oracle version\\n * - Otherwise returns the oracle version at which the pending-settlement position delta can be first settled\\n *\\n * Corresponds to point (b) in the Position settlement flow\\n * @param self The struct to operate on\\n * @param currentVersion The current oracle version index\\n * @return Next oracle version to settle\\n */\\n function settleVersion(PrePosition storage self, uint256 currentVersion) internal view returns (uint256) {\\n uint256 _oracleVersion = self.oracleVersion;\\n return _oracleVersion == 0 ? currentVersion : _oracleVersion + 1;\\n }\\n}\\n\",\"keccak256\":\"0x0c9d701afdb67f0e134a5a0ba33ebb031fa146cb52b5871cbcd6522d9579264b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/ProgramInfo.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\n\\n/// @dev ProgramInfo type\\nstruct ProgramInfo {\\n /// @dev Coordinator for this program\\n uint256 coordinatorId;\\n\\n /// @dev Amount of total maker and taker rewards\\n Position amount;\\n\\n /// @dev start timestamp of the program\\n uint256 start;\\n\\n /// @dev duration of the program (in seconds)\\n uint256 duration;\\n\\n /**\\n * @dev Reward ERC20 token contract\\n * @notice Perennial does not support non-standard ERC20s as reward tokens for incentive programs, including,\\n but not limited to: fee on transfer and rebase tokens. Using such a non-standard token will likely\\n result in loss of funds.\\n */\\n Token18 token;\\n}\\nusing ProgramInfoLib for ProgramInfo global;\\n\\n/**\\n * @title ProgramInfoLib\\n * @notice Library that snapshots the static information for a single program.\\n * @dev This information does not change during the operation of a program.\\n */\\nlibrary ProgramInfoLib {\\n uint256 private constant MIN_DURATION = 1 days;\\n uint256 private constant MAX_DURATION = 2 * 365 days;\\n\\n error ProgramInvalidStartError();\\n error ProgramInvalidDurationError();\\n\\n /**\\n * @notice Validates and creates a new Program\\n * @dev Reverts for invalid programInfos\\n * @param programInfo Un-sanitized static program information\\n */\\n function validate(ProgramInfo memory programInfo) internal view {\\n if (isStarted(programInfo, block.timestamp)) revert ProgramInvalidStartError();\\n if (programInfo.duration < MIN_DURATION || programInfo.duration > MAX_DURATION) revert ProgramInvalidDurationError();\\n }\\n\\n /**\\n * @notice Computes a new program info with the fee taken out of the amount\\n * @param programInfo Original program info\\n * @param incentivizationFee The incentivization fee\\n * @return New program info\\n * @return Fee amount\\n */\\n function deductFee(ProgramInfo memory programInfo, UFixed18 incentivizationFee)\\n internal pure returns (ProgramInfo memory, UFixed18) {\\n Position memory newProgramAmount = programInfo.amount.mul(UFixed18Lib.ONE.sub(incentivizationFee));\\n UFixed18 programFeeAmount = programInfo.amount.sub(newProgramAmount).sum();\\n programInfo.amount = newProgramAmount;\\n return (programInfo, programFeeAmount);\\n }\\n\\n /**\\n * @notice Returns the maker and taker amounts per position share\\n * @param self The ProgramInfo to operate on\\n * @return programFee Amounts per share\\n */\\n function amountPerShare(ProgramInfo memory self) internal pure returns (Accumulator memory) {\\n return self.amount.div(self.duration);\\n }\\n\\n /**\\n * @notice Returns whether the program has started by timestamp `timestamp`\\n * @param self The ProgramInfo to operate on\\n * @param timestamp Timestamp to check for\\n * @return Whether the program has started\\n */\\n function isStarted(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\\n return timestamp >= self.start;\\n }\\n\\n /**\\n * @notice Returns whether the program is completed by timestamp `timestamp`\\n * @param self The ProgramInfo to operate on\\n * @param timestamp Timestamp to check for\\n * @return Whether the program is completed\\n */\\n function isComplete(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\\n return timestamp >= (self.start + self.duration);\\n }\\n}\\n\",\"keccak256\":\"0x280fcaf931b49abaec46b95ccbabaaf856a4b8e8d036413c9c3b3af25585d161\",\"license\":\"Apache-2.0\"},\"contracts/multiinvoker/MultiInvoker.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.15;\\n\\nimport \\\"@equilibria/root/control/unstructured/UInitializable.sol\\\";\\n\\nimport \\\"../interfaces/IMultiInvoker.sol\\\";\\n\\ncontract MultiInvoker is IMultiInvoker, UInitializable {\\n /// @dev USDC stablecoin address\\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\\n\\n /// @dev DSU address\\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\\n\\n /// @dev Batcher address\\n IBatcher public immutable batcher;\\n\\n /// @dev Controller address\\n IController public immutable controller;\\n\\n /// @dev Collateral address\\n ICollateral public immutable collateral;\\n\\n /// @dev Reserve address\\n IEmptySetReserve public immutable reserve;\\n\\n /**\\n * @notice Initializes the immutable contract state\\n * @dev Called at implementation instantiate and constant for that implementation.\\n * @param usdc_ USDC stablecoin address\\n * @param batcher_ Protocol Batcher address\\n * @param reserve_ EmptySet Reserve address\\n * @param controller_ Protocol Controller address\\n */\\n constructor(Token6 usdc_, IBatcher batcher_, IEmptySetReserve reserve_, IController controller_) {\\n USDC = usdc_;\\n batcher = batcher_;\\n controller = controller_;\\n collateral = controller.collateral();\\n DSU = collateral.token();\\n reserve = reserve_;\\n }\\n\\n /**\\n * @notice Initializes the contract state\\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\\n * avoid front-running\\n */\\n function initialize() external initializer(2) {\\n if (address(batcher) != address(0)) {\\n DSU.approve(address(batcher), UFixed18Lib.ZERO);\\n DSU.approve(address(batcher));\\n USDC.approve(address(batcher), UFixed18Lib.ZERO);\\n USDC.approve(address(batcher));\\n }\\n\\n DSU.approve(address(collateral), UFixed18Lib.ZERO);\\n DSU.approve(address(collateral));\\n\\n DSU.approve(address(reserve), UFixed18Lib.ZERO);\\n DSU.approve(address(reserve));\\n USDC.approve(address(reserve), UFixed18Lib.ZERO);\\n USDC.approve(address(reserve));\\n }\\n\\n /**\\n * @notice Executes a list of invocations in order\\n * @param invocations The list of invocations to execute in order\\n */\\n function invoke(Invocation[] calldata invocations) external {\\n\\n for (uint256 i = 0; i < invocations.length; i++) {\\n Invocation memory invocation = invocations[i];\\n\\n // Deposit from `msg.sender` into `account`s `product` collateral account\\n if (invocation.action == PerennialAction.DEPOSIT) {\\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n _deposit(account, product, amount);\\n\\n // Withdraw from `msg.sender`s `product` collateral account to `receiver`\\n } else if (invocation.action == PerennialAction.WITHDRAW) {\\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n _withdraw(receiver, product, amount);\\n\\n // Open a take position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.OPEN_TAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n _openTake(product, amount);\\n\\n // Close a take position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.CLOSE_TAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n _closeTake(product, amount);\\n\\n // Open a make position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.OPEN_MAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n _openMake(product, amount);\\n\\n // Close a make position on behalf of `msg.sender`\\n } else if (invocation.action == PerennialAction.CLOSE_MAKE) {\\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\\n _closeMake(product, amount);\\n\\n // Claim `msg.sender`s incentive reward for `product` programs\\n } else if (invocation.action == PerennialAction.CLAIM) {\\n (IProduct product, uint256[] memory programIds) = abi.decode(invocation.args, (IProduct, uint256[]));\\n _claim(product, programIds);\\n\\n // Wrap `msg.sender`s USDC into DSU and return the DSU to `account`\\n } else if (invocation.action == PerennialAction.WRAP) {\\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\\n _wrap(receiver, amount);\\n\\n // Unwrap `msg.sender`s DSU into USDC and return the USDC to `account`\\n } else if (invocation.action == PerennialAction.UNWRAP) {\\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\\n _unwrap(receiver, amount);\\n\\n // Wrap `msg.sender`s USDC into DSU and deposit into `account`s `product` collateral account\\n } else if (invocation.action == PerennialAction.WRAP_AND_DEPOSIT) {\\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n _wrapAndDeposit(account, product, amount);\\n }\\n\\n // Withdraw DSU from `msg.sender`s `product` collateral account, unwrap into USDC, and return the USDC to `receiver`\\n else if (invocation.action == PerennialAction.WITHDRAW_AND_UNWRAP) {\\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\\n _withdrawAndUnwrap(receiver, product, amount);\\n }\\n\\n // Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account`\\n else if (invocation.action == PerennialAction.VAULT_DEPOSIT) {\\n (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18));\\n _vaultDeposit(account, vault, amount);\\n }\\n\\n // Redeem `shares` from from `vault` on behalf of `msg.sender`\\n else if (invocation.action == PerennialAction.VAULT_REDEEM) {\\n (IPerennialVault vault, UFixed18 shares) = abi.decode(invocation.args, (IPerennialVault, UFixed18));\\n _vaultRedeem(vault, shares);\\n }\\n\\n // Claim assets from `vault` on behalf of `owner`\\n else if (invocation.action == PerennialAction.VAULT_CLAIM) {\\n (address owner, IPerennialVault vault) = abi.decode(invocation.args, (address, IPerennialVault));\\n _vaultClaim(vault, owner);\\n }\\n\\n // Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault`\\n else if (invocation.action == PerennialAction.VAULT_WRAP_AND_DEPOSIT) {\\n (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18));\\n _vaultWrapAndDeposit(account, vault, amount);\\n }\\n }\\n }\\n\\n /**\\n * @notice opens `amount` of take on behalf of `msg.sender` in `product`\\n * @param product Product to increase take position of\\n * @param amount Amount to increase take position by\\n */\\n function _openTake(IProduct product, UFixed18 amount) internal {\\n product.openTakeFor(msg.sender, amount);\\n }\\n\\n /**\\n * @notice closes `amount` of take on behalf of `msg.sender` in `product`\\n * @param product Product to decrease take position of\\n * @param amount Amount to decrease take position by\\n */\\n function _closeTake(IProduct product, UFixed18 amount) internal {\\n product.closeTakeFor(msg.sender, amount);\\n }\\n\\n /**\\n * @notice opens `amount` of make on behalf of `msg.sender` in `product`\\n * @param product Product to increase make position of\\n * @param amount Amount to increase make position by\\n */\\n function _openMake(IProduct product, UFixed18 amount) internal {\\n product.openMakeFor(msg.sender, amount);\\n }\\n\\n /**\\n * @notice closes `amount` of make on behalf of `msg.sender` in `product`\\n * @param product Product to decrease make position of\\n * @param amount Amount to decrease make position by\\n */\\n function _closeMake(IProduct product, UFixed18 amount) internal {\\n product.closeMakeFor(msg.sender, amount);\\n }\\n\\n /**\\n * @notice Deposits `amount` DSU from `msg.sender` into `account`s `product` collateral account\\n * @param account Account to deposit funds on behalf of\\n * @param product Product to deposit funds for\\n * @param amount Amount of DSU to deposit into the collateral account\\n */\\n function _deposit(address account, IProduct product, UFixed18 amount) internal {\\n // Pull the token from the `msg.sender`\\n DSU.pull(msg.sender, amount);\\n\\n // Deposit the amount to the collateral account\\n collateral.depositTo(account, product, amount);\\n }\\n\\n /**\\n * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account to `receiver`\\n * @param receiver address to withdraw funds on behalf of msg.sender to\\n * @param product Product to withdraw frunds from\\n * @param amount Amount of DSU to withdraw out of the collateral account\\n */\\n function _withdraw(address receiver, IProduct product, UFixed18 amount) internal {\\n collateral.withdrawFrom(msg.sender, receiver, IProduct(product), amount);\\n }\\n\\n /**\\n * @notice Claim `msg.sender`s incentive reward for `product` programs\\n * @param product Product to claim\\n */\\n function _claim(IProduct product, uint256[] memory programIds) internal {\\n controller.incentivizer().claimFor(msg.sender, product, programIds);\\n }\\n\\n /**\\n * @notice Wraps `amount` USDC into DSU, pulling from `msg.sender` and sending to `receiver`\\n * @param receiver Address to receive the DSU\\n * @param amount Amount of USDC to wrap\\n */\\n function _wrap(address receiver, UFixed18 amount) internal {\\n // Pull USDC from the `msg.sender`\\n USDC.pull(msg.sender, amount, true);\\n\\n _handleWrap(receiver, amount);\\n }\\n\\n /**\\n * @notice Unwraps `amount` DSU into USDC, pulling from `msg.sender` and sending to `receiver`\\n * @param receiver Address to receive the USDC\\n * @param amount Amount of DSU to unwrap\\n */\\n function _unwrap(address receiver, UFixed18 amount) internal {\\n // Pull the token from the `msg.sender`\\n DSU.pull(msg.sender, amount);\\n\\n _handleUnwrap(receiver, amount);\\n }\\n\\n /**\\n * @notice Wraps `amount` USDC from `msg.sender` into DSU, then deposits the USDC into `account`s `product` collateral account\\n * @param account Account to deposit funds on behalf of\\n * @param product Product to deposit funds for\\n * @param amount Amount of USDC to deposit into the collateral account\\n */\\n function _wrapAndDeposit(address account, IProduct product, UFixed18 amount) internal {\\n // Pull USDC from the `msg.sender`\\n USDC.pull(msg.sender, amount, true);\\n\\n _wrap(address(this), amount);\\n\\n // Deposit the amount to the collateral account\\n collateral.depositTo(account, product, amount);\\n }\\n\\n /**\\n * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account, then unwraps the DSU into USDC and sends it to `receiver`\\n * @param receiver Address to receive the USDC\\n * @param product Product to withdraw funds for\\n * @param amount Amount of DSU to withdraw from the collateral account\\n */\\n function _withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) internal {\\n // Withdraw the amount from the collateral account\\n collateral.withdrawFrom(msg.sender, address(this), product, amount);\\n\\n _unwrap(receiver, amount);\\n }\\n\\n /**\\n * @notice Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account`\\n * @param account Address to receive the vault shares\\n * @param vault Vault to deposit funds into\\n * @param amount Amount of DSU to deposit into the vault\\n */\\n function _vaultDeposit(address account, IPerennialVault vault, UFixed18 amount) internal {\\n // Pull the DSU from the user\\n DSU.pull(msg.sender, amount);\\n\\n // Just-in-time approval to the vault for the amount being deposited\\n DSU.approve(address(vault), amount);\\n\\n // Deposit the DSU to the vault, crediting shares to `account`\\n vault.deposit(amount, account);\\n }\\n\\n /**\\n * @notice Redeems `shares` shares from the vault on behalf of `msg.sender`\\n * @dev Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets\\n * If account is not msg.sender, requires prior spending approval\\n * @param shares Amount of shares to redeem\\n * @param vault Vault to redeem from\\n */\\n function _vaultRedeem(IPerennialVault vault, UFixed18 shares) internal {\\n vault.redeem(shares, msg.sender);\\n }\\n\\n /**\\n * @notice Claims all claimable assets for account, sending assets to account\\n * @param vault Vault to claim from\\n * @param owner Account to claim for\\n */\\n function _vaultClaim(IPerennialVault vault, address owner) internal {\\n vault.claim(owner);\\n }\\n\\n /**\\n * @notice Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault`\\n * @param account Address to receive the vault shares\\n * @param vault Vault to deposit funds into\\n * @param amount Amount of USDC to wrap and deposit into the vault\\n */\\n function _vaultWrapAndDeposit(address account, IPerennialVault vault, UFixed18 amount) internal {\\n // Pull USDC from the `msg.sender`\\n USDC.pull(msg.sender, amount, true);\\n\\n _wrap(address(this), amount);\\n\\n // Just-in-time approval to the vault for the amount being deposited\\n DSU.approve(address(vault), amount);\\n\\n // Deposit the DSU to the vault, crediting shares to `account`\\n vault.deposit(amount, account);\\n }\\n\\n /**\\n * @notice Helper function to wrap `amount` USDC from `msg.sender` into DSU using the batcher or reserve\\n * @param receiver Address to receive the DSU\\n * @param amount Amount of USDC to wrap\\n */\\n function _handleWrap(address receiver, UFixed18 amount) internal {\\n // If the batcher is 0 or doesn't have enough for this wrap, go directly to the reserve\\n if (address(batcher) == address(0) || amount.gt(DSU.balanceOf(address(batcher)))) {\\n reserve.mint(amount);\\n if (receiver != address(this)) DSU.push(receiver, amount);\\n } else {\\n // Wrap the USDC into DSU and return to the receiver\\n batcher.wrap(amount, receiver);\\n }\\n }\\n\\n /**\\n * @notice Helper function to unwrap `amount` DSU into USDC and send to `receiver`\\n * @param receiver Address to receive the USDC\\n * @param amount Amount of DSU to unwrap\\n */\\n function _handleUnwrap(address receiver, UFixed18 amount) internal {\\n // If the batcher is 0 or doesn't have enough for this unwrap, go directly to the reserve\\n if (address(batcher) == address(0) || amount.gt(USDC.balanceOf(address(batcher)))) {\\n reserve.redeem(amount);\\n if (receiver != address(this)) USDC.push(receiver, amount);\\n } else {\\n // Unwrap the DSU into USDC and return to the receiver\\n batcher.unwrap(amount, receiver);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3efd3f34a4cd4b137be93362e9fb7292c4b70539fc3e556b64b0338685aa7106\",\"license\":\"BUSL-1.1\"},\"contracts/multiinvoker/MultiInvokerRollup.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.15;\\n\\nimport \\\"./MultiInvoker.sol\\\";\\nimport \\\"../interfaces/IMultiInvokerRollup.sol\\\";\\n\\n/// @title A calldata-optimized implementation of the Perennial MultiInvoker \\n/// @notice Retains same functionality and `invoke` entry point from inherited MultiInvoker\\ncontract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker {\\n\\n /// @dev the pointer struct for current decoding position in calldata to pass by reference\\n struct PTR {\\n uint256 pos;\\n }\\n\\n /// @dev array of all stored addresses (users, products, vaults, etc) for calldata packing\\n address[] public addressCache;\\n /// @dev index lookup of above array for constructing calldata\\n mapping(address => uint256) public addressLookup;\\n\\n constructor(Token6 usdc, IBatcher _batcher, IEmptySetReserve _reserve, IController _controller) \\n MultiInvoker(usdc, _batcher, _reserve, _controller) \\n { \\n // an empty `addressLookup` resolves to 0\\n // prevents a real address from colliding with 0 index\\n _setAddressCache(address(0));\\n }\\n\\n /// @dev fallback eliminates the need to include function sig in calldata\\n fallback (bytes calldata input) external returns (bytes memory) {\\n _decodeFallbackAndInvoke(input);\\n return \\\"\\\";\\n }\\n\\n /**\\n * @notice this function serves exactly the same as invoke(Invocation[] memory invocations),\\n * but includes logic to handle the highly packed calldata\\n * Encoding Scheme:\\n * [0:1] => uint action \\n * [1:2] => uint length of current encoded type \\n * [2:length] => current encoded type (see individual type decoding functions)\\n */\\n function _decodeFallbackAndInvoke(bytes calldata input) internal {\\n PTR memory ptr = PTR(0);\\n \\n uint256 len = input.length;\\n \\n for (ptr.pos; ptr.pos < len;) {\\n uint8 action = _toUint8(input, ptr);\\n\\n // solidity doesn't like evaluating bytes as enums :/ \\n if (action == 1) { // DEPOSIT\\n address account = _toAddress(input, ptr);\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _deposit(account, IProduct(product), amount);\\n } else if (action == 2) { // WITHDRAW\\n address receiver = _toAddress(input, ptr);\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _withdraw(receiver, IProduct(product), amount);\\n } else if (action == 3) { // OPEN_TAKE\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _openTake(IProduct(product), amount); \\n } else if (action == 4) { // CLOSE_TAKE\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _closeTake(IProduct(product), amount);\\n } else if (action == 5) { // OPEN_MAKE \\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _openMake(IProduct(product), amount);\\n } else if (action == 6) { // CLOSE_MAKE\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _closeMake(IProduct(product), amount);\\n } else if (action == 7) { // CLAIM \\n address product = _toAddress(input, ptr);\\n uint256[] memory programIds = _toUintArray(input, ptr);\\n\\n _claim(IProduct(product), programIds);\\n } else if (action == 8) { // WRAP \\n address receiver = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _wrap(receiver, amount);\\n } else if (action == 9) { // UNWRAP\\n address receiver = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _unwrap(receiver, amount);\\n } else if (action == 10) { // WRAP_AND_DEPOSIT\\n address account = _toAddress(input, ptr);\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n \\n _wrapAndDeposit(account, IProduct(product), amount);\\n } else if (action == 11) { // WITHDRAW_AND_UNWRAP\\n address receiver = _toAddress(input, ptr);\\n address product = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _withdrawAndUnwrap(receiver, IProduct(product), amount);\\n } else if (action == 12) { // VAULT_DEPOSIT\\n address depositer = _toAddress(input, ptr);\\n address vault = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _vaultDeposit(depositer, IPerennialVault(vault), amount);\\n } else if (action == 13) { // VAULT_REDEEM\\n address vault = _toAddress(input, ptr);\\n UFixed18 shares = _toAmount(input, ptr);\\n\\n _vaultRedeem(IPerennialVault(vault), shares);\\n } else if (action == 14) { // VAULT_CLAIM\\n address owner = _toAddress(input, ptr);\\n address vault = _toAddress(input, ptr);\\n\\n _vaultClaim(IPerennialVault(vault), owner);\\n } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT \\n address account = _toAddress(input, ptr);\\n address vault = _toAddress(input, ptr);\\n UFixed18 amount = _toAmount(input, ptr);\\n\\n _vaultWrapAndDeposit(account, IPerennialVault(vault), amount);\\n }\\n }\\n }\\n\\n /// @notice Unchecked sets address in cache\\n /// @param addr Address to add to cache \\n function _setAddressCache(address addr) private {\\n // index of address to be added to cache\\n uint256 idx = addressCache.length;\\n\\n // set address and lookup table\\n addressCache.push(addr);\\n addressLookup[addr] = idx;\\n\\n emit AddressAddedToCache(addr, idx);\\n }\\n\\n /**\\n * @notice Helper function to get address from calldata\\n * @param input Full calldata payload\\n * @param ptr Current index of input to start decoding \\n * @return addr The decoded address\\n */\\n function _toAddress(bytes calldata input, PTR memory ptr) private returns (address addr) {\\n uint8 len = _toUint8(input, ptr);\\n\\n // user is new to registry, add next 20 bytes as address to registry and return address\\n if (len == 0) {\\n addr = _bytesToAddress(input[ptr.pos:ptr.pos+20]);\\n ptr.pos += 20;\\n\\n _setAddressCache(addr);\\n } else {\\n uint256 addrNonceLookup = _bytesToUint256(input[ptr.pos:ptr.pos+len]);\\n ptr.pos += len;\\n\\n addr = _getAddressCache(addrNonceLookup);\\n }\\n }\\n\\n /**\\n * @notice Checked gets the address in cache mapped to the cache index\\n * @dev There is an issue with the calldata if a txn uses cache before caching address\\n * @param idx The cache index\\n * @return addr Address stored at cache index\\n */\\n function _getAddressCache(uint256 idx) private view returns (address addr){\\n addr = addressCache[idx];\\n if (addr == address(0)) revert MultiInvokerRollupInvalidCalldataError();\\n }\\n\\n /**\\n * @notice Wraps next length of bytes as UFixed18\\n * @param input Full calldata payload\\n * @param ptr Current index of input to start decoding\\n * @param ptr Current index of input to start decoding\\n */\\n function _toAmount(bytes calldata input, PTR memory ptr) private view returns (UFixed18 result) {\\n return UFixed18.wrap(_toUint256(input, ptr));\\n }\\n\\n /**\\n * @notice Unpacks next length of bytes as lengths of bytes into array of uint256\\n * @param input Full calldata payload\\n * @param ptr Current index of input to start decoding\\n * @return ProgramIds for CLAIM action \\n */\\n function _toUintArray(bytes calldata input, PTR memory ptr) private pure returns (uint256[] memory) {\\n uint8 arrayLen = _toUint8(input, ptr);\\n\\n uint256[] memory result = new uint256[](arrayLen);\\n\\n for (uint256 count; count < arrayLen;) {\\n uint256 currUint;\\n\\n currUint = _toUint256(input, ptr);\\n\\n result[count] = currUint;\\n\\n ++count;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev This is called in decodeAccount and decodeProduct which both only pass 20 byte slices \\n * @notice Unchecked force of 20 bytes into address\\n * @param input The 20 bytes to be converted to address\\n * @return addr Address representation of `input`\\n */\\n function _bytesToAddress(bytes memory input) private pure returns (address addr) {\\n assembly {\\n addr := mload(add(input, 20))\\n } \\n }\\n\\n /**\\n * @notice Helper function to get uint8 length from calldata\\n * @param input Full calldata payload\\n * @param ptr Current index of input to start decoding \\n * @return res The decoded uint8 length\\n */\\n function _toUint8(bytes calldata input, PTR memory ptr) private pure returns (uint8 res) {\\n res = _bytesToUint8(input[ptr.pos:ptr.pos+1]);\\n ++ptr.pos;\\n }\\n\\n /**\\n * @notice Implementation of GNSPS' standard BytesLib.sol\\n * @param input 1 byte slice to convert to uint8 to decode lengths\\n * @return res The uint8 representation of input\\n */\\n function _bytesToUint8(bytes memory input) private pure returns (uint8 res) {\\n assembly {\\n res := mload(add(input, 0x1))\\n }\\n }\\n\\n /**\\n * @notice Helper function to get uint256 from calldata\\n * @param input Full calldata payload\\n * @param ptr Current index of input to start decoding \\n * @return res The decoded uint256\\n */\\n function _toUint256(bytes calldata input, PTR memory ptr) private pure returns (uint256 res) {\\n uint8 len = _toUint8(input, ptr);\\n\\n res = _bytesToUint256(input[ptr.pos:ptr.pos+len]);\\n ptr.pos += len;\\n }\\n\\n /** \\n * @notice Unchecked loads arbitrarily-sized bytes into a uint\\n * @dev Bytes length enforced as < max word size\\n * @param input The bytes to convert to uint256\\n * @return res The resulting uint256\\n */\\n function _bytesToUint256(bytes memory input) private pure returns (uint256 res) {\\n uint256 len = input.length;\\n\\n // length must not exceed max bytes length of a word/uint\\n if (len > 32) revert MultiInvokerRollupInvalidCalldataError();\\n\\n assembly {\\n res := mload(add(input, 0x20))\\n }\\n\\n // readable right shift to change right padding of mload to left padding\\n res >>= 256 - (len * 8);\\n }\\n}\",\"keccak256\":\"0xee6e9cd25846ee1419e4b852645165c588df314d6488183aa8c1d4a0a5cd2690\",\"license\":\"BUSL-1.1\"}},\"version\":1}", + "bytecode": "0x6101406040523480156200001257600080fd5b506040516200333538038062003335833981016040819052620000359162000207565b6001600160a01b0380851660805280841660c052811660e08190526040805163d8dfeb4560e01b8152905186928692869286929163d8dfeb459160048083019260209291908290030181865afa15801562000094573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ba91906200026f565b6001600160a01b031661010081905260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa15801562000105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012b91906200026f565b6001600160a01b0390811660a052919091166101205250620001529150600090506200015c565b5050505062000296565b60008054600180820183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563820180546001600160a01b0319166001600160a01b038616908117909155808452602091825260409384902083905592518281529192917fd9643d04a6ca8b6a112ed2bb7b77a6087a6d23739fb4cfd7c813fb3a001c3096910160405180910390a25050565b6001600160a01b03811681146200020457600080fd5b50565b600080600080608085870312156200021e57600080fd5b84516200022b81620001ee565b60208601519094506200023e81620001ee565b60408601519093506200025181620001ee565b60608601519092506200026481620001ee565b939692955090935050565b6000602082840312156200028257600080fd5b81516200028f81620001ee565b9392505050565b60805160a05160c05160e0516101005161012051612f1c62000419600039600081816101a10152818161096c015281816109ce01528181610a2e01528181610a9001528181611d260152611f450152600081816101c8015281816108aa0152818161090c01528181611206015281816112c20152611743015260008181610230015261153a01526000818160e5015281816106b00152818161072601528181610788015281816107e80152818161084a01528181611c4c01528181611cc701528181611e4101528181611e7201528181611eed0152612060015260008181610167015281816107040152818161076601528181610888015281816108ea0152818161094a015281816109ac0152818161118b0152818161166d015281816117c30152818161180401528181611ca50152611dce015260008181610140015281816107c60152818161082801528181610a0c01528181610a6e0152818161161c015281816116b80152818161194d01528181611ecb0152611fed0152612f1c6000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063cd3293de11610076578063e56d831e1161005b578063e56d831e146101ea578063f202bc05146101fd578063f77c47911461022b576100be565b8063cd3293de1461019c578063d8dfeb45146101c3576100be565b806389a30271116100a757806389a302711461013b578063a2060bcf14610162578063bdec4a2714610189576100be565b8063025a3a29146100e05780638129fc1c14610131575b60003660606100cd8383610252565b5050604080516020810190915260009052005b6101077f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101396105f7565b005b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101396101973660046127f0565b610b0e565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101076101f8366004612865565b610f80565b61021d61020b3660046128a3565b60016020526000908152604090205481565b604051908152602001610128565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b604080516020810190915260008152815b81518111156105f1576000610279858585610fb7565b90508060ff166001036102c657600061029386868661102f565b905060006102a287878761102f565b905060006102b188888861115a565b90506102be838383611171565b5050506105eb565b8060ff166002036103095760006102de86868661102f565b905060006102ed87878761102f565b905060006102fc88888861115a565b90506102be838383611268565b8060ff1660030361034357600061032186868661102f565b9050600061033087878761115a565b905061033c82826112f1565b50506105eb565b8060ff1660040361037657600061035b86868661102f565b9050600061036a87878761115a565b905061033c828261137c565b8060ff166005036103a957600061038e86868661102f565b9050600061039d87878761115a565b905061033c82826113d5565b8060ff166006036103dc5760006103c186868661102f565b905060006103d087878761115a565b905061033c828261142e565b8060ff1660070361040f5760006103f486868661102f565b90506000610403878787611487565b905061033c8282611538565b8060ff1660080361044257600061042786868661102f565b9050600061043687878761115a565b905061033c8282611602565b8060ff1660090361047557600061045a86868661102f565b9050600061046987878761115a565b905061033c8282611653565b8060ff16600a036104b857600061048d86868661102f565b9050600061049c87878761102f565b905060006104ab88888861115a565b90506102be83838361169e565b8060ff16600b036104fb5760006104d086868661102f565b905060006104df87878761102f565b905060006104ee88888861115a565b90506102be8383836116eb565b8060ff16600c0361053e57600061051386868661102f565b9050600061052287878761102f565b9050600061053188888861115a565b90506102be8383836117a9565b8060ff16600d0361057157600061055686868661102f565b9050600061056587878761115a565b905061033c8282611886565b8060ff16600e036105a457600061058986868661102f565b9050600061059887878761102f565b905061033c81836118df565b8060ff16600f036105eb5760006105bc86868661102f565b905060006105cb87878761102f565b905060006105da88888861115a565b90506105e7838383611933565b5050505b50610263565b50505050565b6002806106227f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b5490565b10610661576040517f1e7a9d95000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61068a7f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b829055565b60017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161561086e5761074c73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611980565b6107ac73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b61080e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000060006119e2565b61086e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b6108d073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611980565b61093073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b61099273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611980565b6109f273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b610a5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000060006119e2565b610ab473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c556040518181527fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f329060200160405180910390a150565b60005b81811015610f7b576000838383818110610b2d57610b2d6128c0565b9050602002810190610b3f91906128ef565b610b48906129d4565b905060018151600f811115610b5f57610b5f612aa4565b03610b9a5760008060008360200151806020019051810190610b819190612ad3565b925092509250610b92838383611171565b505050610f68565b60028151600f811115610baf57610baf612aa4565b03610be25760008060008360200151806020019051810190610bd19190612ad3565b925092509250610b92838383611268565b60038151600f811115610bf757610bf7612aa4565b03610c2c576000808260200151806020019051810190610c179190612b16565b91509150610c2582826112f1565b5050610f68565b60048151600f811115610c4157610c41612aa4565b03610c6f576000808260200151806020019051810190610c619190612b16565b91509150610c25828261137c565b60058151600f811115610c8457610c84612aa4565b03610cb2576000808260200151806020019051810190610ca49190612b16565b91509150610c2582826113d5565b60068151600f811115610cc757610cc7612aa4565b03610cf5576000808260200151806020019051810190610ce79190612b16565b91509150610c25828261142e565b60078151600f811115610d0a57610d0a612aa4565b03610d38576000808260200151806020019051810190610d2a9190612b44565b91509150610c258282611538565b60088151600f811115610d4d57610d4d612aa4565b03610d7b576000808260200151806020019051810190610d6d9190612b16565b91509150610c258282611602565b60098151600f811115610d9057610d90612aa4565b03610dbe576000808260200151806020019051810190610db09190612b16565b91509150610c258282611653565b600a8151600f811115610dd357610dd3612aa4565b03610e065760008060008360200151806020019051810190610df59190612ad3565b925092509250610b9283838361169e565b600b8151600f811115610e1b57610e1b612aa4565b03610e4e5760008060008360200151806020019051810190610e3d9190612ad3565b925092509250610b928383836116eb565b600c8151600f811115610e6357610e63612aa4565b03610e965760008060008360200151806020019051810190610e859190612ad3565b925092509250610b928383836117a9565b600d8151600f811115610eab57610eab612aa4565b03610ed9576000808260200151806020019051810190610ecb9190612b16565b91509150610c258282611886565b600e8151600f811115610eee57610eee612aa4565b03610f1c576000808260200151806020019051810190610f0e9190612c01565b91509150610c2581836118df565b600f8151600f811115610f3157610f31612aa4565b03610f685760008060008360200151806020019051810190610f539190612ad3565b925092509250610f64838383611933565b5050505b5080610f7381612c6a565b915050610b11565b505050565b60008181548110610f9057600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b805160009061101590859085610fce826001612ca2565b92610fdb93929190612cba565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a0f92505050565b905081600001805161102690612c6a565b90529392505050565b60008061103d858585610fb7565b90508060ff166000036110cb5782516110a59086908661105e826014612ca2565b9261106b93929190612cba565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a1692505050565b91506014836000018181516110ba9190612ca2565b9052506110c682611a1d565b611152565b825160009061112b908790876110e460ff871683612ca2565b926110f193929190612cba565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ad492505050565b90508160ff16846000018181516111429190612ca2565b90525061114e81611b3c565b9250505b509392505050565b6000611167848484611bb0565b90505b9392505050565b6111b273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611bfa565b6040517ff213159c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f213159c906064015b600060405180830381600087803b15801561124b57600080fd5b505af115801561125f573d6000803e3d6000fd5b50505050505050565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff84811660248301528381166044830152606482018390527f00000000000000000000000000000000000000000000000000000000000000001690632644131890608401611231565b6040517f9378bf7b0000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff831690639378bf7b906044015b600060405180830381600087803b15801561136057600080fd5b505af1158015611374573d6000803e3d6000fd5b505050505050565b6040517f2131ea4a0000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff831690632131ea4a90604401611346565b6040517f2d2e52be0000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff831690632d2e52be90604401611346565b6040517fe503b0070000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff83169063e503b00790604401611346565b60606000611496858585610fb7565b905060008160ff1667ffffffffffffffff8111156114b6576114b661292d565b6040519080825280602002602001820160405280156114df578160200160208202803683370190505b50905060005b8260ff1681101561152e5760006114fd888888611bb0565b905080838381518110611512576115126128c0565b602090810291909101015261152682612c6a565b9150506114e5565b5095945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c79190612ce4565b73ffffffffffffffffffffffffffffffffffffffff16628240533384846040518463ffffffff1660e01b815260040161134693929190612d01565b61164573ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836001611c1c565b61164f8282611c4a565b5050565b61169473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611bfa565b61164f8282611e70565b6116e173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836001611c1c565b6111b23082611602565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff8381166044830152606482018390527f00000000000000000000000000000000000000000000000000000000000000001690632644131890608401600060405180830381600087803b15801561178757600080fd5b505af115801561179b573d6000803e3d6000fd5b50505050610f7b8382611653565b6117ea73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611bfa565b61182b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383611980565b6040517f6e553f650000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8481166024830152831690636e553f6590604401611231565b6040517f7bde82f20000000000000000000000000000000000000000000000000000000081526004810182905233602482015273ffffffffffffffffffffffffffffffffffffffff831690637bde82f290604401611346565b6040517f1e83409a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690631e83409a90602401611346565b61197673ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836001611c1c565b6117ea3082611602565b610f7b73ffffffffffffffffffffffffffffffffffffffff8416838361208f565b61164f73ffffffffffffffffffffffffffffffffffffffff8316827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61208f565b610f7b826119f183600061228f565b73ffffffffffffffffffffffffffffffffffffffff8616919061208f565b6001015190565b6014015190565b60008054600180820183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155808452602091825260409384902083905592518281529192917fd9643d04a6ca8b6a112ed2bb7b77a6087a6d23739fb4cfd7c813fb3a001c3096910160405180910390a25050565b80516000906020811115611b14576040517f56c4491100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301519150611b26816008612d71565b611b3290610100612dae565b9190911c92915050565b6000808281548110611b5057611b506128c0565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080611bab576040517f56c4491100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600080611bbe858585610fb7565b8351909150611bd7908690866110e460ff861683612ca2565b91508060ff1683600001818151611bee9190612ca2565b90525090949350505050565b610f7b73ffffffffffffffffffffffffffffffffffffffff84168330846122c2565b6105f18330611c2b858561228f565b73ffffffffffffffffffffffffffffffffffffffff88169291906122c2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580611cf25750611cf2611ceb73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000612320565b82906123b4565b15611df5576040517fa0712d68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a0712d6890602401600060405180830381600087803b158015611d7f57600080fd5b505af1158015611d93573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff8216301461164f5761164f73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001683836123ca565b6040517f13bac8200000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f000000000000000000000000000000000000000000000000000000000000000016906313bac82090604401611346565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580611f115750611f11611ceb73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006123eb565b15612014576040517fdb006a75000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063db006a7590602401600060405180830381600087803b158015611f9e57600080fd5b505af1158015611fb2573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff8216301461164f5761164f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383612487565b6040517f7647691d0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f00000000000000000000000000000000000000000000000000000000000000001690637647691d90604401611346565b80158061212f57506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212d9190612dc5565b155b6121bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610658565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f7b9084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124b4565b6000816122aa576122a564e8d4a5100084612e0d565b6122b9565b6122b98364e8d4a510006125c0565b90505b92915050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105f19085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161220d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a0823190602401602060405180830381865afa158015612390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122b99190612dc5565b60006123c083836125f2565b6002149392505050565b610f7b73ffffffffffffffffffffffffffffffffffffffff84168383612627565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000916122b9918516906370a0823190602401602060405180830381865afa15801561245e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124829190612dc5565b61267d565b610f7b8261249683600061228f565b73ffffffffffffffffffffffffffffffffffffffff86169190612627565b6000612516826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661268e9092919063ffffffff16565b805190915015610f7b57808060200190518101906125349190612e21565b610f7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610658565b60006125cc8284612e43565b156125d85760016125db565b60005b60ff166125e88385612e0d565b6122b99190612ca2565b6000828280821115612609576002925050506122bc565b8082101561261c576000925050506122bc565b506001949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f7b9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161220d565b60006122bc64e8d4a5100083612d71565b606061116784846000858573ffffffffffffffffffffffffffffffffffffffff85163b612717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610658565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516127409190612e83565b60006040518083038185875af1925050503d806000811461277d576040519150601f19603f3d011682016040523d82523d6000602084013e612782565b606091505b509150915061279282828661279d565b979650505050505050565b606083156127ac57508161116a565b8251156127bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106589190612e95565b6000806020838503121561280357600080fd5b823567ffffffffffffffff8082111561281b57600080fd5b818501915085601f83011261282f57600080fd5b81358181111561283e57600080fd5b8660208260051b850101111561285357600080fd5b60209290920196919550909350505050565b60006020828403121561287757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146128a057600080fd5b50565b6000602082840312156128b557600080fd5b813561116a8161287e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261292357600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561297f5761297f61292d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156129cc576129cc61292d565b604052919050565b6000604082360312156129e657600080fd5b6129ee61295c565b8235601081106129fd57600080fd5b815260208381013567ffffffffffffffff80821115612a1b57600080fd5b9085019036601f830112612a2e57600080fd5b813581811115612a4057612a4061292d565b612a70847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612985565b91508082523684828501011115612a8657600080fd5b80848401858401376000908201840152918301919091525092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080600060608486031215612ae857600080fd5b8351612af38161287e565b6020850151909350612b048161287e565b80925050604084015190509250925092565b60008060408385031215612b2957600080fd5b8251612b348161287e565b6020939093015192949293505050565b60008060408385031215612b5757600080fd5b8251612b628161287e565b8092505060208084015167ffffffffffffffff80821115612b8257600080fd5b818601915086601f830112612b9657600080fd5b815181811115612ba857612ba861292d565b8060051b9150612bb9848301612985565b8181529183018401918481019089841115612bd357600080fd5b938501935b83851015612bf157845182529385019390850190612bd8565b8096505050505050509250929050565b60008060408385031215612c1457600080fd5b8251612c1f8161287e565b6020840151909250612c308161287e565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c9b57612c9b612c3b565b5060010190565b60008219821115612cb557612cb5612c3b565b500190565b60008085851115612cca57600080fd5b83861115612cd757600080fd5b5050820193919092039150565b600060208284031215612cf657600080fd5b815161116a8161287e565b60006060820173ffffffffffffffffffffffffffffffffffffffff8087168452602081871681860152606060408601528291508551808452608086019250818701935060005b81811015612d6357845184529382019392820192600101612d47565b509198975050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612da957612da9612c3b565b500290565b600082821015612dc057612dc0612c3b565b500390565b600060208284031215612dd757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612e1c57612e1c612dde565b500490565b600060208284031215612e3357600080fd5b8151801515811461116a57600080fd5b600082612e5257612e52612dde565b500690565b60005b83811015612e72578181015183820152602001612e5a565b838111156105f15750506000910152565b60008251612923818460208701612e57565b6020815260008251806020840152612eb4816040850160208701612e57565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220ac12fa468503eb0bb50f493c094bb9593b1f43c3bbcf705362a1427d9a2f6e7464736f6c634300080f0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063cd3293de11610076578063e56d831e1161005b578063e56d831e146101ea578063f202bc05146101fd578063f77c47911461022b576100be565b8063cd3293de1461019c578063d8dfeb45146101c3576100be565b806389a30271116100a757806389a302711461013b578063a2060bcf14610162578063bdec4a2714610189576100be565b8063025a3a29146100e05780638129fc1c14610131575b60003660606100cd8383610252565b5050604080516020810190915260009052005b6101077f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101396105f7565b005b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101396101973660046127f0565b610b0e565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b6101076101f8366004612865565b610f80565b61021d61020b3660046128a3565b60016020526000908152604090205481565b604051908152602001610128565b6101077f000000000000000000000000000000000000000000000000000000000000000081565b604080516020810190915260008152815b81518111156105f1576000610279858585610fb7565b90508060ff166001036102c657600061029386868661102f565b905060006102a287878761102f565b905060006102b188888861115a565b90506102be838383611171565b5050506105eb565b8060ff166002036103095760006102de86868661102f565b905060006102ed87878761102f565b905060006102fc88888861115a565b90506102be838383611268565b8060ff1660030361034357600061032186868661102f565b9050600061033087878761115a565b905061033c82826112f1565b50506105eb565b8060ff1660040361037657600061035b86868661102f565b9050600061036a87878761115a565b905061033c828261137c565b8060ff166005036103a957600061038e86868661102f565b9050600061039d87878761115a565b905061033c82826113d5565b8060ff166006036103dc5760006103c186868661102f565b905060006103d087878761115a565b905061033c828261142e565b8060ff1660070361040f5760006103f486868661102f565b90506000610403878787611487565b905061033c8282611538565b8060ff1660080361044257600061042786868661102f565b9050600061043687878761115a565b905061033c8282611602565b8060ff1660090361047557600061045a86868661102f565b9050600061046987878761115a565b905061033c8282611653565b8060ff16600a036104b857600061048d86868661102f565b9050600061049c87878761102f565b905060006104ab88888861115a565b90506102be83838361169e565b8060ff16600b036104fb5760006104d086868661102f565b905060006104df87878761102f565b905060006104ee88888861115a565b90506102be8383836116eb565b8060ff16600c0361053e57600061051386868661102f565b9050600061052287878761102f565b9050600061053188888861115a565b90506102be8383836117a9565b8060ff16600d0361057157600061055686868661102f565b9050600061056587878761115a565b905061033c8282611886565b8060ff16600e036105a457600061058986868661102f565b9050600061059887878761102f565b905061033c81836118df565b8060ff16600f036105eb5760006105bc86868661102f565b905060006105cb87878761102f565b905060006105da88888861115a565b90506105e7838383611933565b5050505b50610263565b50505050565b6002806106227f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b5490565b10610661576040517f1e7a9d95000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61068a7f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b829055565b60017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161561086e5761074c73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611980565b6107ac73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b61080e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000060006119e2565b61086e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b6108d073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611980565b61093073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b61099273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611980565b6109f273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b610a5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000060006119e2565b610ab473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119a1565b60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c556040518181527fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f329060200160405180910390a150565b60005b81811015610f7b576000838383818110610b2d57610b2d6128c0565b9050602002810190610b3f91906128ef565b610b48906129d4565b905060018151600f811115610b5f57610b5f612aa4565b03610b9a5760008060008360200151806020019051810190610b819190612ad3565b925092509250610b92838383611171565b505050610f68565b60028151600f811115610baf57610baf612aa4565b03610be25760008060008360200151806020019051810190610bd19190612ad3565b925092509250610b92838383611268565b60038151600f811115610bf757610bf7612aa4565b03610c2c576000808260200151806020019051810190610c179190612b16565b91509150610c2582826112f1565b5050610f68565b60048151600f811115610c4157610c41612aa4565b03610c6f576000808260200151806020019051810190610c619190612b16565b91509150610c25828261137c565b60058151600f811115610c8457610c84612aa4565b03610cb2576000808260200151806020019051810190610ca49190612b16565b91509150610c2582826113d5565b60068151600f811115610cc757610cc7612aa4565b03610cf5576000808260200151806020019051810190610ce79190612b16565b91509150610c25828261142e565b60078151600f811115610d0a57610d0a612aa4565b03610d38576000808260200151806020019051810190610d2a9190612b44565b91509150610c258282611538565b60088151600f811115610d4d57610d4d612aa4565b03610d7b576000808260200151806020019051810190610d6d9190612b16565b91509150610c258282611602565b60098151600f811115610d9057610d90612aa4565b03610dbe576000808260200151806020019051810190610db09190612b16565b91509150610c258282611653565b600a8151600f811115610dd357610dd3612aa4565b03610e065760008060008360200151806020019051810190610df59190612ad3565b925092509250610b9283838361169e565b600b8151600f811115610e1b57610e1b612aa4565b03610e4e5760008060008360200151806020019051810190610e3d9190612ad3565b925092509250610b928383836116eb565b600c8151600f811115610e6357610e63612aa4565b03610e965760008060008360200151806020019051810190610e859190612ad3565b925092509250610b928383836117a9565b600d8151600f811115610eab57610eab612aa4565b03610ed9576000808260200151806020019051810190610ecb9190612b16565b91509150610c258282611886565b600e8151600f811115610eee57610eee612aa4565b03610f1c576000808260200151806020019051810190610f0e9190612c01565b91509150610c2581836118df565b600f8151600f811115610f3157610f31612aa4565b03610f685760008060008360200151806020019051810190610f539190612ad3565b925092509250610f64838383611933565b5050505b5080610f7381612c6a565b915050610b11565b505050565b60008181548110610f9057600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b805160009061101590859085610fce826001612ca2565b92610fdb93929190612cba565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a0f92505050565b905081600001805161102690612c6a565b90529392505050565b60008061103d858585610fb7565b90508060ff166000036110cb5782516110a59086908661105e826014612ca2565b9261106b93929190612cba565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a1692505050565b91506014836000018181516110ba9190612ca2565b9052506110c682611a1d565b611152565b825160009061112b908790876110e460ff871683612ca2565b926110f193929190612cba565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ad492505050565b90508160ff16846000018181516111429190612ca2565b90525061114e81611b3c565b9250505b509392505050565b6000611167848484611bb0565b90505b9392505050565b6111b273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611bfa565b6040517ff213159c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018390527f0000000000000000000000000000000000000000000000000000000000000000169063f213159c906064015b600060405180830381600087803b15801561124b57600080fd5b505af115801561125f573d6000803e3d6000fd5b50505050505050565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff84811660248301528381166044830152606482018390527f00000000000000000000000000000000000000000000000000000000000000001690632644131890608401611231565b6040517f9378bf7b0000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff831690639378bf7b906044015b600060405180830381600087803b15801561136057600080fd5b505af1158015611374573d6000803e3d6000fd5b505050505050565b6040517f2131ea4a0000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff831690632131ea4a90604401611346565b6040517f2d2e52be0000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff831690632d2e52be90604401611346565b6040517fe503b0070000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff83169063e503b00790604401611346565b60606000611496858585610fb7565b905060008160ff1667ffffffffffffffff8111156114b6576114b661292d565b6040519080825280602002602001820160405280156114df578160200160208202803683370190505b50905060005b8260ff1681101561152e5760006114fd888888611bb0565b905080838381518110611512576115126128c0565b602090810291909101015261152682612c6a565b9150506114e5565b5095945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c79190612ce4565b73ffffffffffffffffffffffffffffffffffffffff16628240533384846040518463ffffffff1660e01b815260040161134693929190612d01565b61164573ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836001611c1c565b61164f8282611c4a565b5050565b61169473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611bfa565b61164f8282611e70565b6116e173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836001611c1c565b6111b23082611602565b6040517f2644131800000000000000000000000000000000000000000000000000000000815233600482015230602482015273ffffffffffffffffffffffffffffffffffffffff8381166044830152606482018390527f00000000000000000000000000000000000000000000000000000000000000001690632644131890608401600060405180830381600087803b15801561178757600080fd5b505af115801561179b573d6000803e3d6000fd5b50505050610f7b8382611653565b6117ea73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611bfa565b61182b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383611980565b6040517f6e553f650000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8481166024830152831690636e553f6590604401611231565b6040517f7bde82f20000000000000000000000000000000000000000000000000000000081526004810182905233602482015273ffffffffffffffffffffffffffffffffffffffff831690637bde82f290604401611346565b6040517f1e83409a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690631e83409a90602401611346565b61197673ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836001611c1c565b6117ea3082611602565b610f7b73ffffffffffffffffffffffffffffffffffffffff8416838361208f565b61164f73ffffffffffffffffffffffffffffffffffffffff8316827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61208f565b610f7b826119f183600061228f565b73ffffffffffffffffffffffffffffffffffffffff8616919061208f565b6001015190565b6014015190565b60008054600180820183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616908117909155808452602091825260409384902083905592518281529192917fd9643d04a6ca8b6a112ed2bb7b77a6087a6d23739fb4cfd7c813fb3a001c3096910160405180910390a25050565b80516000906020811115611b14576040517f56c4491100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301519150611b26816008612d71565b611b3290610100612dae565b9190911c92915050565b6000808281548110611b5057611b506128c0565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905080611bab576040517f56c4491100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600080611bbe858585610fb7565b8351909150611bd7908690866110e460ff861683612ca2565b91508060ff1683600001818151611bee9190612ca2565b90525090949350505050565b610f7b73ffffffffffffffffffffffffffffffffffffffff84168330846122c2565b6105f18330611c2b858561228f565b73ffffffffffffffffffffffffffffffffffffffff88169291906122c2565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580611cf25750611cf2611ceb73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000612320565b82906123b4565b15611df5576040517fa0712d68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a0712d6890602401600060405180830381600087803b158015611d7f57600080fd5b505af1158015611d93573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff8216301461164f5761164f73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001683836123ca565b6040517f13bac8200000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f000000000000000000000000000000000000000000000000000000000000000016906313bac82090604401611346565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580611f115750611f11611ceb73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006123eb565b15612014576040517fdb006a75000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063db006a7590602401600060405180830381600087803b158015611f9e57600080fd5b505af1158015611fb2573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff8216301461164f5761164f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383612487565b6040517f7647691d0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff83811660248301527f00000000000000000000000000000000000000000000000000000000000000001690637647691d90604401611346565b80158061212f57506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212d9190612dc5565b155b6121bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610658565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f7b9084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526124b4565b6000816122aa576122a564e8d4a5100084612e0d565b6122b9565b6122b98364e8d4a510006125c0565b90505b92915050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105f19085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161220d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a0823190602401602060405180830381865afa158015612390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122b99190612dc5565b60006123c083836125f2565b6002149392505050565b610f7b73ffffffffffffffffffffffffffffffffffffffff84168383612627565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000916122b9918516906370a0823190602401602060405180830381865afa15801561245e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124829190612dc5565b61267d565b610f7b8261249683600061228f565b73ffffffffffffffffffffffffffffffffffffffff86169190612627565b6000612516826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661268e9092919063ffffffff16565b805190915015610f7b57808060200190518101906125349190612e21565b610f7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610658565b60006125cc8284612e43565b156125d85760016125db565b60005b60ff166125e88385612e0d565b6122b99190612ca2565b6000828280821115612609576002925050506122bc565b8082101561261c576000925050506122bc565b506001949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f7b9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161220d565b60006122bc64e8d4a5100083612d71565b606061116784846000858573ffffffffffffffffffffffffffffffffffffffff85163b612717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610658565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516127409190612e83565b60006040518083038185875af1925050503d806000811461277d576040519150601f19603f3d011682016040523d82523d6000602084013e612782565b606091505b509150915061279282828661279d565b979650505050505050565b606083156127ac57508161116a565b8251156127bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106589190612e95565b6000806020838503121561280357600080fd5b823567ffffffffffffffff8082111561281b57600080fd5b818501915085601f83011261282f57600080fd5b81358181111561283e57600080fd5b8660208260051b850101111561285357600080fd5b60209290920196919550909350505050565b60006020828403121561287757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff811681146128a057600080fd5b50565b6000602082840312156128b557600080fd5b813561116a8161287e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261292357600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561297f5761297f61292d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156129cc576129cc61292d565b604052919050565b6000604082360312156129e657600080fd5b6129ee61295c565b8235601081106129fd57600080fd5b815260208381013567ffffffffffffffff80821115612a1b57600080fd5b9085019036601f830112612a2e57600080fd5b813581811115612a4057612a4061292d565b612a70847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612985565b91508082523684828501011115612a8657600080fd5b80848401858401376000908201840152918301919091525092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600080600060608486031215612ae857600080fd5b8351612af38161287e565b6020850151909350612b048161287e565b80925050604084015190509250925092565b60008060408385031215612b2957600080fd5b8251612b348161287e565b6020939093015192949293505050565b60008060408385031215612b5757600080fd5b8251612b628161287e565b8092505060208084015167ffffffffffffffff80821115612b8257600080fd5b818601915086601f830112612b9657600080fd5b815181811115612ba857612ba861292d565b8060051b9150612bb9848301612985565b8181529183018401918481019089841115612bd357600080fd5b938501935b83851015612bf157845182529385019390850190612bd8565b8096505050505050509250929050565b60008060408385031215612c1457600080fd5b8251612c1f8161287e565b6020840151909250612c308161287e565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c9b57612c9b612c3b565b5060010190565b60008219821115612cb557612cb5612c3b565b500190565b60008085851115612cca57600080fd5b83861115612cd757600080fd5b5050820193919092039150565b600060208284031215612cf657600080fd5b815161116a8161287e565b60006060820173ffffffffffffffffffffffffffffffffffffffff8087168452602081871681860152606060408601528291508551808452608086019250818701935060005b81811015612d6357845184529382019392820192600101612d47565b509198975050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612da957612da9612c3b565b500290565b600082821015612dc057612dc0612c3b565b500390565b600060208284031215612dd757600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082612e1c57612e1c612dde565b500490565b600060208284031215612e3357600080fd5b8151801515811461116a57600080fd5b600082612e5257612e52612dde565b500690565b60005b83811015612e72578181015183820152602001612e5a565b838111156105f15750506000910152565b60008251612923818460208701612e57565b6020815260008251806020840152612eb4816040850160208701612e57565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220ac12fa468503eb0bb50f493c094bb9593b1f43c3bbcf705362a1427d9a2f6e7464736f6c634300080f0033", "devdoc": { + "errors": { + "MultiInvokerRollupInvalidCalldataError()": [ + { + "details": "reverts when calldata has an issue. causes: length of bytes in a uint > || cache index empty" + } + ] + }, "kind": "dev", "methods": { - "constructor": { - "details": "Called at implementation instantiate and constant for that implementation.", - "params": { - "batcher_": "Protocol Batcher address", - "controller_": "Protocol Controller address", - "reserve_": "EmptySet Reserve address", - "usdc_": "USDC stablecoin address" - } - }, "initialize()": { "details": "Must be called atomically as part of the upgradeable proxy deployment to avoid front-running" }, @@ -221,33 +299,19 @@ } }, "stateVariables": { - "DSU": { - "details": "DSU address" - }, - "USDC": { - "details": "USDC stablecoin address" - }, - "batcher": { - "details": "Batcher address" - }, - "collateral": { - "details": "Collateral address" + "addressCache": { + "details": "array of all stored addresses (users, products, vaults, etc) for calldata packing" }, - "controller": { - "details": "Controller address" - }, - "reserve": { - "details": "Reserve address" + "addressLookup": { + "details": "index lookup of above array for constructing calldata" } }, + "title": "A calldata-optimized implementation of the Perennial MultiInvoker ", "version": 1 }, "userdoc": { "kind": "user", "methods": { - "constructor": { - "notice": "Initializes the immutable contract state" - }, "initialize()": { "notice": "Initializes the contract state" }, @@ -255,10 +319,52 @@ "notice": "Executes a list of invocations in order" } }, + "notice": "Retains same functionality and `invoke` entry point from inherited MultiInvoker", "version": 1 }, "storageLayout": { - "storage": [], - "types": null + "storage": [ + { + "astId": 20398, + "contract": "contracts/multiinvoker/MultiInvokerRollup.sol:MultiInvokerRollup", + "label": "addressCache", + "offset": 0, + "slot": "0", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 20403, + "contract": "contracts/multiinvoker/MultiInvokerRollup.sol:MultiInvokerRollup", + "label": "addressLookup", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } } } diff --git a/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Proxy.json b/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Proxy.json index aac0bc1c..a88c1093 100644 --- a/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Proxy.json +++ b/packages/perennial/deployments/arbitrumGoerli/MultiInvoker_Proxy.json @@ -1,5 +1,5 @@ { - "address": "0xdc518208c11159844188f647413a427Cbd70a3b6", + "address": "0x86ccFAdd81433929e04e32C056A2eEFc08359B60", "abi": [ { "inputs": [ @@ -146,49 +146,49 @@ "type": "receive" } ], - "transactionHash": "0xa69e4fdb676be08809c56747d5c818bc818f8bc64997abdca27eca40846ae2d6", + "transactionHash": "0x40b4fcf796e8091822b2233e80d36ddffb0c81f282dcf2975ad70a46fc6ca1d5", "receipt": { "to": null, - "from": "0x66a7fDB96C583c59597de16d8b2B989231415339", - "contractAddress": "0xdc518208c11159844188f647413a427Cbd70a3b6", + "from": "0x2aF0AE203e2Fa0710EAB8D25884F8aa723517B69", + "contractAddress": "0x86ccFAdd81433929e04e32C056A2eEFc08359B60", "transactionIndex": 1, - "gasUsed": "690597", - "logsBloom": "0x00080000000000040000000002000000400000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000100000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000200000000000000000000000000000000020000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x15e9ddb4cb84dfa2d09177e41fd734063ca76e1521440ab3e4b41536e9987852", - "transactionHash": "0xa69e4fdb676be08809c56747d5c818bc818f8bc64997abdca27eca40846ae2d6", + "gasUsed": "18488036", + "logsBloom": "0x00000000000000000000000000000000400040000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000040000000000000000000000000000000000000000000000002000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000300000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x9ae5077fe9614adf6f069294e979a60f3d70302eb2451f9cc3ea415cc8e6e01d", + "transactionHash": "0x40b4fcf796e8091822b2233e80d36ddffb0c81f282dcf2975ad70a46fc6ca1d5", "logs": [ { "transactionIndex": 1, - "blockNumber": 4214004, - "transactionHash": "0xa69e4fdb676be08809c56747d5c818bc818f8bc64997abdca27eca40846ae2d6", - "address": "0xdc518208c11159844188f647413a427Cbd70a3b6", + "blockNumber": 14356257, + "transactionHash": "0x40b4fcf796e8091822b2233e80d36ddffb0c81f282dcf2975ad70a46fc6ca1d5", + "address": "0x86ccFAdd81433929e04e32C056A2eEFc08359B60", "topics": [ "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", - "0x000000000000000000000000e77076d3eee12da1d7402ff4e6ca12a8d99fce8b" + "0x0000000000000000000000008d89b54276e50e8400d51aec2312340fd0e4c006" ], "data": "0x", "logIndex": 0, - "blockHash": "0x15e9ddb4cb84dfa2d09177e41fd734063ca76e1521440ab3e4b41536e9987852" + "blockHash": "0x9ae5077fe9614adf6f069294e979a60f3d70302eb2451f9cc3ea415cc8e6e01d" }, { "transactionIndex": 1, - "blockNumber": 4214004, - "transactionHash": "0xa69e4fdb676be08809c56747d5c818bc818f8bc64997abdca27eca40846ae2d6", - "address": "0xdc518208c11159844188f647413a427Cbd70a3b6", + "blockNumber": 14356257, + "transactionHash": "0x40b4fcf796e8091822b2233e80d36ddffb0c81f282dcf2975ad70a46fc6ca1d5", + "address": "0x86ccFAdd81433929e04e32C056A2eEFc08359B60", "topics": ["0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"], "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fc20bcca96bde758e9c69151d99cecfeae3ab37e", "logIndex": 1, - "blockHash": "0x15e9ddb4cb84dfa2d09177e41fd734063ca76e1521440ab3e4b41536e9987852" + "blockHash": "0x9ae5077fe9614adf6f069294e979a60f3d70302eb2451f9cc3ea415cc8e6e01d" } ], - "blockNumber": 4214004, - "cumulativeGasUsed": "690597", + "blockNumber": 14356257, + "cumulativeGasUsed": "18488036", "status": 1, "byzantium": true }, - "args": ["0xE77076D3EeE12dA1d7402Ff4e6Ca12A8d99FcE8B", "0xfC20BccA96BDE758E9C69151d99cEcfEAE3AB37E", "0x"], - "numDeployments": 1, - "solcInputHash": "0954eb4c5a9afab2c0aa2d884eb92458", + "args": ["0x8D89B54276E50E8400d51aec2312340Fd0e4c006", "0xfC20BccA96BDE758E9C69151d99cEcfEAE3AB37E", "0x"], + "numDeployments": 2, + "solcInputHash": "181d5952a5d0fca85831e55cf8991318", "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x60806040526040516200112838038062001128833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b600080516020620010e1833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b600080516020620010c183398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e98383604051806060016040528060278152602001620011016027913962000381565b9392505050565b60006200021a600080516020620010c183398151915260001b6200046760201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd600080516020620010c183398151915260001b6200046760201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b620002b81760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd600080516020620010e183398151915260001b6200046760201b6200022e1760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610a2980620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109cd602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff1685604051610573919061095f565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a2919061097b565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b8381111561043e5750506000910152565b60008251610971818460208701610933565b9190910192915050565b602081526000825180602084015261099a816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a4b930408c511c08d53f1ec84bb13fe259938b06e5d586d6adc4fc27200abe6c64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109cd602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff1685604051610573919061095f565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a2919061097b565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b8381111561043e5750506000910152565b60008251610971818460208701610933565b9190910192915050565b602081526000825180602084015261099a816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a4b930408c511c08d53f1ec84bb13fe259938b06e5d586d6adc4fc27200abe6c64736f6c634300080f0033", diff --git a/packages/perennial/deployments/arbitrumGoerli/solcInputs/181d5952a5d0fca85831e55cf8991318.json b/packages/perennial/deployments/arbitrumGoerli/solcInputs/181d5952a5d0fca85831e55cf8991318.json new file mode 100644 index 00000000..eda213ed --- /dev/null +++ b/packages/perennial/deployments/arbitrumGoerli/solcInputs/181d5952a5d0fca85831e55cf8991318.json @@ -0,0 +1,420 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorInterface {\n function latestAnswer() external view returns (int256);\n\n function latestTimestamp() external view returns (uint256);\n\n function latestRound() external view returns (uint256);\n\n function getAnswer(uint256 roundId) external view returns (int256);\n\n function getTimestamp(uint256 roundId) external view returns (uint256);\n\n event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n\n event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}\n" + }, + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./AggregatorInterface.sol\";\nimport \"./AggregatorV3Interface.sol\";\n\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}\n" + }, + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n" + }, + "@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./AggregatorV2V3Interface.sol\";\n\ninterface FeedRegistryInterface {\n struct Phase {\n uint16 phaseId;\n uint80 startingAggregatorRoundId;\n uint80 endingAggregatorRoundId;\n }\n\n event FeedProposed(\n address indexed asset,\n address indexed denomination,\n address indexed proposedAggregator,\n address currentAggregator,\n address sender\n );\n event FeedConfirmed(\n address indexed asset,\n address indexed denomination,\n address indexed latestAggregator,\n address previousAggregator,\n uint16 nextPhaseId,\n address sender\n );\n\n // V3 AggregatorV3Interface\n\n function decimals(address base, address quote) external view returns (uint8);\n\n function description(address base, address quote) external view returns (string memory);\n\n function version(address base, address quote) external view returns (uint256);\n\n function latestRoundData(address base, address quote)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function getRoundData(\n address base,\n address quote,\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n // V2 AggregatorInterface\n\n function latestAnswer(address base, address quote) external view returns (int256 answer);\n\n function latestTimestamp(address base, address quote) external view returns (uint256 timestamp);\n\n function latestRound(address base, address quote) external view returns (uint256 roundId);\n\n function getAnswer(\n address base,\n address quote,\n uint256 roundId\n ) external view returns (int256 answer);\n\n function getTimestamp(\n address base,\n address quote,\n uint256 roundId\n ) external view returns (uint256 timestamp);\n\n // Registry getters\n\n function getFeed(address base, address quote) external view returns (AggregatorV2V3Interface aggregator);\n\n function getPhaseFeed(\n address base,\n address quote,\n uint16 phaseId\n ) external view returns (AggregatorV2V3Interface aggregator);\n\n function isFeedEnabled(address aggregator) external view returns (bool);\n\n function getPhase(\n address base,\n address quote,\n uint16 phaseId\n ) external view returns (Phase memory phase);\n\n // Round helpers\n\n function getRoundFeed(\n address base,\n address quote,\n uint80 roundId\n ) external view returns (AggregatorV2V3Interface aggregator);\n\n function getPhaseRange(\n address base,\n address quote,\n uint16 phaseId\n ) external view returns (uint80 startingRoundId, uint80 endingRoundId);\n\n function getPreviousRoundId(\n address base,\n address quote,\n uint80 roundId\n ) external view returns (uint80 previousRoundId);\n\n function getNextRoundId(\n address base,\n address quote,\n uint80 roundId\n ) external view returns (uint80 nextRoundId);\n\n // Feed management\n\n function proposeFeed(\n address base,\n address quote,\n address aggregator\n ) external;\n\n function confirmFeed(\n address base,\n address quote,\n address aggregator\n ) external;\n\n // Proposed aggregator\n\n function getProposedFeed(address base, address quote)\n external\n view\n returns (AggregatorV2V3Interface proposedAggregator);\n\n function proposedGetRoundData(\n address base,\n address quote,\n uint80 roundId\n )\n external\n view\n returns (\n uint80 id,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function proposedLatestRoundData(address base, address quote)\n external\n view\n returns (\n uint80 id,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n // Phases\n function getCurrentPhaseId(address base, address quote) external view returns (uint16 currentPhaseId);\n}\n" + }, + "@equilibria/emptyset-batcher/batcher/Batcher.sol": { + "content": "//SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"@equilibria/root/control/unstructured/UOwnable.sol\";\nimport \"../interfaces/IBatcher.sol\";\nimport \"../interfaces/IEmptySetReserve.sol\";\n\nabstract contract Batcher is IBatcher, UOwnable {\n /// @dev Reserve address\n IEmptySetReserve public immutable RESERVE; // solhint-disable-line var-name-mixedcase\n\n /// @dev DSU address\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n\n /// @dev USDC address\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n /**\n * @notice Initializes the Batcher\n * @dev Called at implementation instantiate and constant for that implementation.\n * @param reserve EmptySet Reserve Aaddress\n * @param dsu DSU Token address\n * @param usdc USDC Token Address\n */\n constructor(IEmptySetReserve reserve, Token18 dsu, Token6 usdc) {\n RESERVE = reserve;\n DSU = dsu;\n USDC = usdc;\n\n DSU.approve(address(RESERVE));\n USDC.approve(address(RESERVE));\n\n __UOwnable__initialize();\n }\n\n /**\n * @notice Total USDC and DSU balance of the Batcher\n * @return Balance of DSU + balance of USDC\n */\n function totalBalance() public view returns (UFixed18) {\n return DSU.balanceOf().add(USDC.balanceOf());\n }\n\n /**\n * @notice Wraps `amount` of USDC, returned DSU to `to`\n * @param amount Amount of USDC to wrap\n * @param to Receiving address of resulting DSU\n */\n function wrap(UFixed18 amount, address to) external {\n _wrap(amount, to);\n emit Wrap(to, amount);\n }\n\n /**\n * @notice Pulls USDC from the `msg.sender` and pushes DSU to `to`\n * @dev Rounds USDC amount up if `amount` exceeds USDC decimal precision. Overrideable by implementation\n * @param amount Amount of USDC to pull\n * @param to Receiving address of resulting DSU\n */\n function _wrap(UFixed18 amount, address to) virtual internal {\n USDC.pull(msg.sender, amount, true);\n DSU.push(to, amount);\n }\n\n /**\n * @notice Unwraps `amount` of DSU, returned USDC to `to`\n * @param amount Amount of DSU to unwrap\n * @param to Receiving address of resulting USDC\n */\n function unwrap(UFixed18 amount, address to) external {\n _unwrap(amount, to);\n emit Unwrap(to, amount);\n }\n\n /**\n * @notice Pulls DSU from the `msg.sender` and pushes USDC to `to`\n * @dev Rounds USDC amount down if `amount` exceeds USDC decimal precision. Overrideable by implementation\n * @param amount Amount of DSU to pull\n * @param to Receiving address of resulting USDC\n */\n function _unwrap(UFixed18 amount, address to) virtual internal {\n DSU.pull(msg.sender, amount);\n USDC.push(to, amount);\n }\n\n /**\n * @notice Rebalances the USDC and DSU in the Batcher to maintain target balances\n * @dev Reverts if the new total balance is less than before\n */\n function rebalance() public {\n (UFixed18 usdcBalance, UFixed18 dsuBalance) = (USDC.balanceOf(), DSU.balanceOf());\n\n _rebalance(usdcBalance, dsuBalance);\n\n UFixed18 newDsuBalance = DSU.balanceOf();\n (UFixed18 oldBalance, UFixed18 newBalance) = (usdcBalance.add(dsuBalance), totalBalance());\n if (oldBalance.gt(newBalance)) revert BatcherBalanceMismatchError(oldBalance, newBalance);\n\n emit Rebalance(\n newDsuBalance.gt(dsuBalance) ? newDsuBalance.sub(dsuBalance) : UFixed18Lib.ZERO,\n dsuBalance.gt(newDsuBalance) ? dsuBalance.sub(newDsuBalance) : UFixed18Lib.ZERO\n );\n }\n\n /// @dev Hook for implementation for custom rebalance logic\n function _rebalance(UFixed18 usdcBalance, UFixed18 dsuBalance) virtual internal;\n\n /**\n * @notice Closes the Batcher. Repaying debt to Reserve and returning excess USDC to owner.\n */\n function close() external onlyOwner {\n _close();\n\n UFixed18 dsuBalance = DSU.balanceOf();\n UFixed18 repayAmount = UFixed18Lib.min(RESERVE.debt(address(this)), dsuBalance);\n UFixed18 returnAmount = dsuBalance.sub(repayAmount);\n\n RESERVE.repay(address(this), repayAmount);\n\n // If there is any excess DSU, redeem it for USDC and send to the owner\n if (!returnAmount.isZero()) {\n RESERVE.redeem(returnAmount);\n USDC.push(owner(), returnAmount);\n }\n\n emit Close(dsuBalance);\n }\n\n /// @dev Hook for implementation for custom close logic\n function _close() virtual internal;\n}\n" + }, + "@equilibria/emptyset-batcher/interfaces/IBatcher.sol": { + "content": "//SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"../interfaces/IEmptySetReserve.sol\";\n\ninterface IBatcher {\n event Wrap(address indexed to, UFixed18 amount);\n event Unwrap(address indexed to, UFixed18 amount);\n event Rebalance(UFixed18 newMinted, UFixed18 newRedeemed);\n event Close(UFixed18 amount);\n\n error BatcherNotImplementedError();\n error BatcherBalanceMismatchError(UFixed18 oldBalance, UFixed18 newBalance);\n\n function RESERVE() external view returns (IEmptySetReserve); // solhint-disable-line func-name-mixedcase\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\n function totalBalance() external view returns (UFixed18);\n function wrap(UFixed18 amount, address to) external;\n function unwrap(UFixed18 amount, address to) external;\n function rebalance() external;\n}\n" + }, + "@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol": { + "content": "//SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\n\ninterface IEmptySetReserve {\n event Redeem(address indexed account, uint256 costAmount, uint256 redeemAmount);\n event Mint(address indexed account, uint256 mintAmount, uint256 costAmount);\n event Repay(address indexed account, uint256 repayAmount);\n\n function debt(address borrower) external view returns (UFixed18);\n function repay(address borrower, UFixed18 amount) external;\n function mint(UFixed18 amount) external;\n function redeem(UFixed18 amount) external;\n}\n" + }, + "@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport \"./interfaces/IOracleProvider.sol\";\nimport \"./types/ChainlinkRegistry.sol\";\n\n/**\n * @title ChainlinkOracle\n * @notice Chainlink implementation of the IOracle interface.\n * @dev One instance per Chainlink price feed should be deployed. Multiple products may use the same\n * ChainlinkOracle instance if their payoff functions are based on the same underlying oracle.\n * This implementation only support non-negative prices.\n */\ncontract ChainlinkOracle is IOracleProvider {\n /// @dev Chainlink registry feed address\n ChainlinkRegistry public immutable registry;\n\n /// @dev Base token address for the Chainlink oracle\n address public immutable base;\n\n /// @dev Quote token address for the Chainlink oracle\n address public immutable quote;\n\n /// @dev Decimal offset used to normalize chainlink price to 18 decimals\n int256 private immutable _decimalOffset;\n\n /// @dev Mapping of the starting data for each underlying phase\n Phase[] private _phases;\n\n struct Phase {\n uint128 startingVersion;\n uint128 startingRoundId;\n }\n\n /**\n * @notice Initializes the contract state\n * @param registry_ Chainlink price feed registry\n * @param base_ base currency for feed\n * @param quote_ quote currency for feed\n */\n constructor(ChainlinkRegistry registry_, address base_, address quote_) {\n registry = registry_;\n base = base_;\n quote = quote_;\n\n // phaseId is 1-indexed, skip index 0\n _phases.push(Phase(uint128(0), uint128(0)));\n // phaseId is 1-indexed, first phase starts as version 0\n _phases.push(Phase(uint128(0), uint128(registry_.getStartingRoundId(base_, quote_, 1))));\n\n _decimalOffset = SafeCast.toInt256(10 ** registry_.decimals(base, quote));\n }\n\n /**\n * @notice Checks for a new price and updates the internal phase annotation state accordingly\n * @return The current oracle version after sync\n */\n function sync() external returns (OracleVersion memory) {\n // Fetch latest round\n ChainlinkRound memory round = registry.getLatestRound(base, quote);\n\n // Revert if the round id is 0\n if (uint64(round.roundId) == 0) revert InvalidOracleRound();\n\n // Update phase annotation when new phase detected\n while (round.phaseId() > _latestPhaseId()) {\n _phases.push(\n Phase(\n uint128(registry.getRoundCount(base, quote, _latestPhaseId())) +\n _phases[_phases.length - 1].startingVersion,\n uint128(registry.getStartingRoundId(base, quote, _latestPhaseId() + 1))\n )\n );\n }\n\n // Return packaged oracle version\n return _buildOracleVersion(round);\n }\n\n /**\n * @notice Returns the current oracle version\n * @return oracleVersion Current oracle version\n */\n function currentVersion() public view returns (OracleVersion memory oracleVersion) {\n return _buildOracleVersion(registry.getLatestRound(base, quote));\n }\n\n /**\n * @notice Returns the current oracle version\n * @param version The version of which to lookup\n * @return oracleVersion Oracle version at version `version`\n */\n function atVersion(uint256 version) public view returns (OracleVersion memory oracleVersion) {\n return _buildOracleVersion(registry.getRound(base, quote, _versionToRoundId(version)), version);\n }\n\n /**\n * @notice Builds an oracle version object from a Chainlink round object\n * @dev Computes the version for the round\n * @param round Chainlink round to build from\n * @return Built oracle version\n */\n function _buildOracleVersion(ChainlinkRound memory round) private view returns (OracleVersion memory) {\n Phase memory phase = _phases[round.phaseId()];\n uint256 version = uint256(phase.startingVersion) + round.roundId - uint256(phase.startingRoundId);\n return _buildOracleVersion(round, version);\n }\n\n /**\n * @notice Builds an oracle version object from a Chainlink round object\n * @param round Chainlink round to build from\n * @param version Determined version for the round\n * @return Built oracle version\n */\n function _buildOracleVersion(ChainlinkRound memory round, uint256 version)\n private view returns (OracleVersion memory) {\n Fixed18 price = Fixed18Lib.ratio(round.answer, _decimalOffset);\n return OracleVersion({ version: version, timestamp: round.timestamp, price: price });\n }\n\n /**\n * @notice Computes the chainlink round ID from a version\n * @param version Version to compute from\n * @return Chainlink round ID\n */\n function _versionToRoundId(uint256 version) private view returns (uint256) {\n Phase memory phase = _versionToPhase(version);\n return uint256(phase.startingRoundId) + version - uint256(phase.startingVersion);\n }\n\n /**\n * @notice Computes the chainlink phase ID from a version\n * @param version Version to compute from\n * @return phase Chainlink phase\n */\n function _versionToPhase(uint256 version) private view returns (Phase memory phase) {\n uint256 phaseId = _latestPhaseId();\n phase = _phases[phaseId];\n while (uint256(phase.startingVersion) > version) {\n phaseId--;\n phase = _phases[phaseId];\n }\n }\n\n /**\n * @notice Returns the latest phase ID that this contract has seen via `sync()`\n * @return Latest seen phase ID\n */\n function _latestPhaseId() private view returns (uint16) {\n return uint16(_phases.length - 1);\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\n\ninterface IOracleProvider {\n /// @dev Error for invalid oracle round\n error InvalidOracleRound();\n\n /// @dev A singular oracle version with its corresponding data\n struct OracleVersion {\n /// @dev The iterative version\n uint256 version;\n\n /// @dev the timestamp of the oracle update\n uint256 timestamp;\n\n /// @dev The oracle price of the corresponding version\n Fixed18 price;\n }\n\n function sync() external returns (OracleVersion memory);\n function currentVersion() external view returns (OracleVersion memory);\n function atVersion(uint256 oracleVersion) external view returns (OracleVersion memory);\n}\n" + }, + "@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\nimport \"./interfaces/IOracleProvider.sol\";\n\n/**\n * @title ReservoirFeedOracle\n * @notice Reservoir implementation of the IOracle interface, using Reservoir's AggregatorV3Interface adaptors\n * @dev This is a naive implementation which pushes all validation to the underlying. No staleness checks are possible\n This oracle should not be used for regular Chainlink Data Feeds\n */\ncontract ReservoirFeedOracle is IOracleProvider {\n error InvalidOracleVersion();\n\n /// @dev Chainlink price feed to read from\n AggregatorV3Interface public immutable feed;\n\n /// @dev Decimal offset used to normalize chainlink price to 18 decimals\n int256 private immutable _decimalOffset;\n\n /// @dev Which underlying round to consider version 0: version = roundId - _versionOffset\n uint80 private immutable _versionOffset;\n\n /**\n * @notice Initializes the contract state\n * @param feed_ Reservoir price feed\n * @param versionOffset_ Version offset from source round ID\n */\n constructor(AggregatorV3Interface feed_, uint80 versionOffset_) {\n feed = feed_;\n _versionOffset = versionOffset_;\n _decimalOffset = SafeCast.toInt256(10 ** feed_.decimals());\n }\n\n /**\n * @notice Checks for a new price. Does not perform staleness validation as the underlying oracle does not\n support this.\n * @return The current oracle version after sync\n */\n function sync() external view returns (OracleVersion memory) {\n (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.latestRoundData();\n\n return _buildOracleVersion(roundId, feedPrice, timestamp);\n }\n\n /**\n * @notice Returns the current oracle version\n * @return oracleVersion Current oracle version\n */\n function currentVersion() public view returns (OracleVersion memory oracleVersion) {\n (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.latestRoundData();\n\n return _buildOracleVersion(roundId, feedPrice, timestamp);\n }\n\n /**\n * @notice Returns the oracle version specified\n * @dev Converts the passed in version to a roundID by adding _versionOffset\n * @param version The version of which to lookup\n * @return oracleVersion Oracle version at version `version`\n */\n function atVersion(uint256 version) public view returns (OracleVersion memory oracleVersion) {\n // To convert from version to roundId, we add the versionOffset\n uint256 feedRoundID = version + _versionOffset;\n if (feedRoundID > type(uint80).max) revert InvalidOracleVersion();\n (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.getRoundData(uint80(feedRoundID));\n\n return _buildOracleVersion(roundId, feedPrice, timestamp);\n }\n\n /**\n * @notice Builds an oracle version object from a Chainlink round object\n * @dev Converts the passed in roundID to a version by subtracting _versionOffset\n * @param roundId ReservoirRoundId round to build from\n * @param feedPrice price returns by the oracle\n * @param timestamp round timestamps\n * @return Built oracle version\n */\n function _buildOracleVersion(uint80 roundId, int256 feedPrice, uint256 timestamp)\n private view returns (OracleVersion memory) {\n Fixed18 price = Fixed18Lib.ratio(feedPrice, _decimalOffset);\n\n // To convert from roundId to version, we subtract the versionOffset\n return OracleVersion({ version: roundId - _versionOffset, timestamp: timestamp, price: price });\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol\";\n\ncontract PassthroughChainlinkFeed {\n FeedRegistryInterface private _underlying;\n\n constructor(FeedRegistryInterface underlying_) {\n _underlying = underlying_;\n }\n\n function decimals(address base, address quote) external view returns (uint8) {\n return _underlying.decimals(base, quote);\n }\n\n function getRoundData(address base, address quote, uint80 roundId) external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.getRoundData(base, quote, roundId);\n }\n\n function getPhaseRange(address base, address quote, uint16 phaseId) external view returns (uint80, uint80) {\n return _underlying.getPhaseRange(base, quote, phaseId);\n }\n\n function latestRoundData(address base, address quote) external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.latestRoundData(base, quote);\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\ncontract PassthroughDataFeed {\n AggregatorV3Interface private _underlying;\n\n constructor(AggregatorV3Interface underlying_) {\n _underlying = underlying_;\n }\n\n function decimals() external view returns (uint8) {\n return _underlying.decimals();\n }\n\n function getRoundData(uint80 roundId) external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.getRoundData(roundId);\n }\n\n function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.latestRoundData();\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\ncontract TestnetChainlinkFeedRegistry {\n mapping(address => mapping(address => uint8)) public decimals;\n\n function registerFeed(address base, address quote, uint8 newDecimals) external {\n decimals[base][quote] = newDecimals;\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/types/ChainlinkRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol\";\nimport \"./ChainlinkRound.sol\";\n\n/// @dev ChainlinkRegistry type\ntype ChainlinkRegistry is address;\nusing ChainlinkRegistryLib for ChainlinkRegistry global;\n\n/**\n * @title ChainlinkRegistryLib\n * @notice Library that manages interfacing with the Chainlink Feed Registry.\n */\nlibrary ChainlinkRegistryLib {\n /**\n * @notice Returns the decimal amount for a specific feed\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @return Decimal amount\n */\n function decimals(ChainlinkRegistry self, address base, address quote) internal view returns (uint8) {\n return FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).decimals(base, quote);\n }\n\n /**\n * @notice Returns the latest round data for a specific feed\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @return Latest round data\n */\n function getLatestRound(ChainlinkRegistry self, address base, address quote) internal view returns (ChainlinkRound memory) {\n (uint80 roundId, int256 answer, , uint256 updatedAt, ) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).latestRoundData(base, quote);\n return ChainlinkRound({roundId: roundId, timestamp: updatedAt, answer: answer});\n }\n\n /**\n * @notice Returns a specific round's data for a specific feed\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @param roundId The specific round to fetch data for\n * @return Specific round's data\n */\n function getRound(ChainlinkRegistry self, address base, address quote, uint256 roundId) internal view returns (ChainlinkRound memory) {\n (, int256 answer, , uint256 updatedAt, ) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).getRoundData(base, quote, uint80(roundId));\n return ChainlinkRound({roundId: roundId, timestamp: updatedAt, answer: answer});\n }\n\n\n /**\n * @notice Returns the first round ID for a specific phase ID\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @param phaseId The specific phase to fetch data for\n * @return startingRoundId The starting round ID for the phase\n */\n function getStartingRoundId(ChainlinkRegistry self, address base, address quote, uint16 phaseId)\n internal view returns (uint80 startingRoundId) {\n (startingRoundId, ) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).getPhaseRange(base, quote, phaseId);\n }\n\n /**\n * @notice Returns the quantity of rounds for a specific phase ID\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @param phaseId The specific phase to fetch data for\n * @return The quantity of rounds for the phase\n */\n function getRoundCount(ChainlinkRegistry self, address base, address quote, uint256 phaseId)\n internal view returns (uint256) {\n (uint80 startingRoundId, uint80 endingRoundId) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).getPhaseRange(base, quote, uint16(phaseId));\n\n // If the phase has a starting and ending roundId of 0, then there are no rounds.\n // Convert phase rounds to aggregator rounds to check ID\n if (uint64(startingRoundId) == 0 && uint64(endingRoundId) == 0) return 0;\n return uint256(endingRoundId - startingRoundId + 1);\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/types/ChainlinkRound.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @dev ChainlinkRound type\nstruct ChainlinkRound {\n uint256 timestamp;\n int256 answer;\n uint256 roundId;\n}\nusing ChainlinkRoundLib for ChainlinkRound global;\n\n/**\n * @title ChainlinkRoundLib\n * @notice Library that manages Chainlink round parsing.\n */\nlibrary ChainlinkRoundLib {\n /// @dev Phase ID offset location in the round ID\n uint256 constant private PHASE_OFFSET = 64;\n\n /**\n * @notice Computes the chainlink phase ID from a round\n * @param self Round to compute from\n * @return Chainlink phase ID\n */\n function phaseId(ChainlinkRound memory self) internal pure returns (uint16) {\n return uint16(self.roundId >> PHASE_OFFSET);\n }\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwnable/UCrossChainOwnable_Arbitrum.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol\";\nimport \"./UCrossChainOwnable.sol\";\n\n/**\n * @title UCrossChainOwnable_Arbitrum\n * @notice Library to manage the cross-chain ownership lifecycle of Arbitrum upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance. This contract\n * is specific to the Arbitrum L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwnable} for initialization and update usage.\n */\nabstract contract UCrossChainOwnable_Arbitrum is CrossChainEnabledArbitrumL2, UCrossChainOwnable {\n constructor() CrossChainEnabledArbitrumL2() {}\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwnable/UCrossChainOwnable_Optimism.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol\";\nimport \"./UCrossChainOwnable.sol\";\n\n/**\n * @title UCrossChainOwnable_Optimism\n * @notice Library to manage the cross-chain ownership lifecycle of upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance. This contract\n * is specific to the Optimism L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwnable} for initialization and update usage.\n */\nabstract contract UCrossChainOwnable_Optimism is CrossChainEnabledOptimism, UCrossChainOwnable {\n /// @dev System address for the CrossDomainMessenger. This address is ONLY valid on the L2 side\n address public constant L2_CROSS_DOMAIN_MESSENGER_ADDRESS = address(0x4200000000000000000000000000000000000007);\n\n constructor() CrossChainEnabledOptimism(L2_CROSS_DOMAIN_MESSENGER_ADDRESS) {}\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwnable/UCrossChainOwnable.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/crosschain/CrossChainEnabled.sol\";\nimport \"../UOwnable.sol\";\nimport \"../../../storage/UStorage.sol\";\n\n/**\n * @title UCrossChainOwnable\n * @notice Library to manage the cross-chain ownership lifecycle of upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance.\n *\n * Upon initialization, the `owner` will be set to the `msg.sender` of the initialize method.\n * Ownership should then be transferred to the cross-chain owner via the `updatePendingOwner`\n * and `acceptedPending` owner methods. Upon accepting ownership via the cross-chain address,\n * a fuse will be tripped, preventing same-chain ownership going forward.\n */\nabstract contract UCrossChainOwnable is UOwnable, CrossChainEnabled {\n BoolStorage private constant _crossChainRestricted = BoolStorage.wrap(keccak256(\"equilibria.root.UCrossChainOwnable.crossChainRestricted\"));\n function crossChainRestricted() public view returns (bool) { return _crossChainRestricted.read(); }\n\n function _beforeAcceptOwner() internal override {\n if (!crossChainRestricted()) _crossChainRestricted.store(true);\n }\n\n function _sender() internal view override returns (address) {\n if (crossChainRestricted()) return _crossChainSender();\n return msg.sender;\n }\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Arbitrum.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../CrossChainOwnable/UCrossChainOwnable_Arbitrum.sol\";\nimport \"./UCrossChainOwner.sol\";\n\n/**\n * @title UCrossChainOwner_Arbitrum\n * @notice Contract to act as an owner of other contracts\n * @dev This contract is designed to act as an owner of any Ownable contract, allowing\n * Cross Chain Ownership without modification to the underlying ownable contract. This contract\n * is specific to the Arbitrum L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwner} for initialization and usage.\n */\ncontract UCrossChainOwner_Arbitrum is UCrossChainOwner, UCrossChainOwnable_Arbitrum { }\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Optimism.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../CrossChainOwnable/UCrossChainOwnable_Optimism.sol\";\nimport \"./UCrossChainOwner.sol\";\n\n/**\n * @title UCrossChainOwner_Arbitrum\n * @notice Contract to act as an owner of other contracts\n * @dev This contract is designed to act as an owner of any Ownable contract, allowing\n * Cross Chain Ownership without modification to the underlying ownable contract. This contract\n * is specific to the Optimism L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwner} for initialization and usage.\n */\ncontract UCrossChainOwner_Optimism is UCrossChainOwner, UCrossChainOwnable_Optimism { }\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../CrossChainOwnable/UCrossChainOwnable.sol\";\n\n/**\n * @title UCrossChainOwner\n * @notice Contract to act as an owner of other contracts\n * @dev This contract is designed to act as an owner of any Ownable contract, allowing\n * Cross Chain Ownership without modification to the underlying ownable contract\n */\nabstract contract UCrossChainOwner is UCrossChainOwnable {\n function initialize() external initializer(1) {\n super.__UOwnable__initialize();\n }\n\n function execute(\n address payable to,\n bytes memory data,\n uint256 value\n ) payable external onlyOwner returns (bytes memory ret) {\n if (data.length == 0) {\n Address.sendValue(to, value);\n } else {\n ret = Address.functionCallWithValue(to, data, value);\n }\n }\n}\n" + }, + "@equilibria/root/control/unstructured/UInitializable.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../../storage/UStorage.sol\";\n\n/**\n * @title UInitializable\n * @notice Library to manage the initialization lifecycle of upgradeable contracts\n * @dev `UInitializable` allows the creation of pseudo-constructors for upgradeable contracts. One\n * `initializer` should be declared per top-level contract. Child contracts can use the `onlyInitializer`\n * modifier to tag their internal initialization functions to ensure that they can only be called\n * from a top-level `initializer` or a constructor.\n */\nabstract contract UInitializable {\n error UInitializableZeroVersionError();\n error UInitializableAlreadyInitializedError(uint256 version);\n error UInitializableNotInitializingError();\n\n event Initialized(uint256 version);\n\n /// @dev The initialized flag\n Uint256Storage private constant _version = Uint256Storage.wrap(keccak256(\"equilibria.root.UInitializable.version\"));\n\n /// @dev The initializing flag\n BoolStorage private constant _initializing = BoolStorage.wrap(keccak256(\"equilibria.root.UInitializable.initializing\"));\n\n /// @dev Can only be called once per version, `version` is 1-indexed\n modifier initializer(uint256 version) {\n if (version == 0) revert UInitializableZeroVersionError();\n if (_version.read() >= version) revert UInitializableAlreadyInitializedError(version);\n\n _version.store(version);\n _initializing.store(true);\n\n _;\n\n _initializing.store(false);\n emit Initialized(version);\n }\n\n /// @dev Can only be called from an initializer or constructor\n modifier onlyInitializer() {\n if (!_constructing() && !_initializing.read()) revert UInitializableNotInitializingError();\n _;\n }\n\n /**\n * @notice Returns whether the contract is currently being constructed\n * @dev {Address.isContract} returns false for contracts currently in the process of being constructed\n * @return Whether the contract is currently being constructed\n */\n function _constructing() private view returns (bool) {\n return !Address.isContract(address(this));\n }\n}\n" + }, + "@equilibria/root/control/unstructured/UOwnable.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./UInitializable.sol\";\nimport \"../../storage/UStorage.sol\";\n\n/**\n * @title UOwnable\n * @notice Library to manage the ownership lifecycle of upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance.\n */\nabstract contract UOwnable is UInitializable {\n event OwnerUpdated(address indexed newOwner);\n event PendingOwnerUpdated(address indexed newPendingOwner);\n\n error UOwnableNotOwnerError(address sender);\n error UOwnableNotPendingOwnerError(address sender);\n\n /// @dev The owner address\n AddressStorage private constant _owner = AddressStorage.wrap(keccak256(\"equilibria.root.UOwnable.owner\"));\n function owner() public view returns (address) { return _owner.read(); }\n\n /// @dev The pending owner address\n AddressStorage private constant _pendingOwner = AddressStorage.wrap(keccak256(\"equilibria.root.UOwnable.pendingOwner\"));\n function pendingOwner() public view returns (address) { return _pendingOwner.read(); }\n\n /**\n * @notice Initializes the contract setting `msg.sender` as the initial owner\n */\n function __UOwnable__initialize() internal onlyInitializer {\n _updateOwner(_sender());\n }\n\n /**\n * @notice Updates the new pending owner\n * @dev Can only be called by the current owner\n * New owner does not take affect until that address calls `acceptOwner()`\n * @param newPendingOwner New pending owner address\n */\n function updatePendingOwner(address newPendingOwner) public onlyOwner {\n _pendingOwner.store(newPendingOwner);\n emit PendingOwnerUpdated(newPendingOwner);\n }\n\n /**\n * @notice Accepts and transfers the ownership of the contract to the pending owner\n * @dev Can only be called by the pending owner to ensure correctness. Calls to the `_beforeAcceptOwner` hook\n * to perform logic before updating ownership.\n */\n function acceptOwner() public {\n _beforeAcceptOwner();\n\n if (_sender() != pendingOwner()) revert UOwnableNotPendingOwnerError(_sender());\n\n _updateOwner(pendingOwner());\n updatePendingOwner(address(0));\n }\n\n\n /// @dev Hook for inheriting contracts to perform logic before accepting ownership\n function _beforeAcceptOwner() internal virtual {}\n\n /**\n * @notice Updates the owner address\n * @param newOwner New owner address\n */\n function _updateOwner(address newOwner) private {\n _owner.store(newOwner);\n emit OwnerUpdated(newOwner);\n }\n\n function _sender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n /// @dev Throws if called by any account other than the owner\n modifier onlyOwner {\n if (owner() != _sender()) revert UOwnableNotOwnerError(_sender());\n _;\n }\n}\n" + }, + "@equilibria/root/control/unstructured/UReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./UInitializable.sol\";\nimport \"../../storage/UStorage.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n *\n * NOTE: This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern, so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance.\n */\nabstract contract UReentrancyGuard is UInitializable {\n error UReentrancyGuardReentrantCallError();\n\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n /**\n * @dev unstructured storage slot for the reentrancy status\n */\n Uint256Storage private constant _status = Uint256Storage.wrap(keccak256(\"equilibria.root.UReentrancyGuard.status\"));\n\n /**\n * @dev Initializes the contract setting the status to _NOT_ENTERED.\n */\n function __UReentrancyGuard__initialize() internal onlyInitializer {\n _status.store(_NOT_ENTERED);\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n if (_status.read() == _ENTERED) revert UReentrancyGuardReentrantCallError();\n\n // Any calls to nonReentrant after this point will fail\n _status.store(_ENTERED);\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status.store(_NOT_ENTERED);\n }\n}\n" + }, + "@equilibria/root/curve/CurveMath.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../number/types/UFixed18.sol\";\nimport \"../number/types/Fixed18.sol\";\n\n/**\n * @title CurveMath\n * @notice Library for managing math operations for utilization curves.\n */\nlibrary CurveMath {\n error CurveMathOutOfBoundsError();\n\n /**\n * @notice Computes a linear interpolation between two points\n * @param startX First point's x-coordinate\n * @param startY First point's y-coordinate\n * @param endX Second point's x-coordinate\n * @param endY Second point's y-coordinate\n * @param targetX x-coordinate to interpolate\n * @return y-coordinate for `targetX` along the line from (`startX`, `startY`) -> (`endX`, `endY`)\n */\n function linearInterpolation(\n UFixed18 startX,\n Fixed18 startY,\n UFixed18 endX,\n Fixed18 endY,\n UFixed18 targetX\n ) internal pure returns (Fixed18) {\n if (targetX.lt(startX) || targetX.gt(endX)) revert CurveMathOutOfBoundsError();\n\n UFixed18 xRange = endX.sub(startX);\n Fixed18 yRange = endY.sub(startY);\n UFixed18 xRatio = targetX.sub(startX).div(xRange);\n return yRange.mul(Fixed18Lib.from(xRatio)).add(startY);\n }\n}\n" + }, + "@equilibria/root/curve/types/JumpRateUtilizationCurve.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../CurveMath.sol\";\nimport \"../../number/types/PackedUFixed18.sol\";\nimport \"../../number/types/PackedFixed18.sol\";\n\n/// @dev JumpRateUtilizationCurve type\nstruct JumpRateUtilizationCurve {\n PackedFixed18 minRate;\n PackedFixed18 maxRate;\n PackedFixed18 targetRate;\n PackedUFixed18 targetUtilization;\n}\nusing JumpRateUtilizationCurveLib for JumpRateUtilizationCurve global;\ntype JumpRateUtilizationCurveStorage is bytes32;\nusing JumpRateUtilizationCurveStorageLib for JumpRateUtilizationCurveStorage global;\n\n/**\n * @title JumpRateUtilizationCurveLib\n * @notice Library for the Jump Rate utilization curve type\n */\nlibrary JumpRateUtilizationCurveLib {\n /**\n * @notice Computes the corresponding rate for a utilization ratio\n * @param utilization The utilization ratio\n * @return The corresponding rate\n */\n function compute(JumpRateUtilizationCurve memory self, UFixed18 utilization) internal pure returns (Fixed18) {\n UFixed18 targetUtilization = self.targetUtilization.unpack();\n if (utilization.lt(targetUtilization)) {\n return CurveMath.linearInterpolation(\n UFixed18Lib.ZERO,\n self.minRate.unpack(),\n targetUtilization,\n self.targetRate.unpack(),\n utilization\n );\n }\n if (utilization.lt(UFixed18Lib.ONE)) {\n return CurveMath.linearInterpolation(\n targetUtilization,\n self.targetRate.unpack(),\n UFixed18Lib.ONE,\n self.maxRate.unpack(),\n utilization\n );\n }\n return self.maxRate.unpack();\n }\n}\n\nlibrary JumpRateUtilizationCurveStorageLib {\n function read(JumpRateUtilizationCurveStorage self) internal view returns (JumpRateUtilizationCurve memory) {\n return _storagePointer(self);\n }\n\n function store(JumpRateUtilizationCurveStorage self, JumpRateUtilizationCurve memory value) internal {\n JumpRateUtilizationCurve storage storagePointer = _storagePointer(self);\n\n storagePointer.minRate = value.minRate;\n storagePointer.maxRate = value.maxRate;\n storagePointer.targetRate = value.targetRate;\n storagePointer.targetUtilization = value.targetUtilization;\n }\n\n function _storagePointer(JumpRateUtilizationCurveStorage self)\n private pure returns (JumpRateUtilizationCurve storage pointer) {\n assembly { pointer.slot := self }\n }\n}" + }, + "@equilibria/root/number/types/Fixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport \"./UFixed18.sol\";\nimport \"./PackedFixed18.sol\";\n\n/// @dev Fixed18 type\ntype Fixed18 is int256;\nusing Fixed18Lib for Fixed18 global;\ntype Fixed18Storage is bytes32;\nusing Fixed18StorageLib for Fixed18Storage global;\n\n/**\n * @title Fixed18Lib\n * @notice Library for the signed fixed-decimal type.\n */\nlibrary Fixed18Lib {\n error Fixed18OverflowError(uint256 value);\n error Fixed18PackingOverflowError(int256 value);\n error Fixed18PackingUnderflowError(int256 value);\n\n int256 private constant BASE = 1e18;\n Fixed18 public constant ZERO = Fixed18.wrap(0);\n Fixed18 public constant ONE = Fixed18.wrap(BASE);\n Fixed18 public constant NEG_ONE = Fixed18.wrap(-1 * BASE);\n Fixed18 public constant MAX = Fixed18.wrap(type(int256).max);\n Fixed18 public constant MIN = Fixed18.wrap(type(int256).min);\n\n /**\n * @notice Creates a signed fixed-decimal from an unsigned fixed-decimal\n * @param a Unsigned fixed-decimal\n * @return New signed fixed-decimal\n */\n function from(UFixed18 a) internal pure returns (Fixed18) {\n uint256 value = UFixed18.unwrap(a);\n if (value > uint256(type(int256).max)) revert Fixed18OverflowError(value);\n return Fixed18.wrap(int256(value));\n }\n\n /**\n * @notice Creates a signed fixed-decimal from a sign and an unsigned fixed-decimal\n * @param s Sign\n * @param m Unsigned fixed-decimal magnitude\n * @return New signed fixed-decimal\n */\n function from(int256 s, UFixed18 m) internal pure returns (Fixed18) {\n if (s > 0) return from(m);\n if (s < 0) return Fixed18.wrap(-1 * Fixed18.unwrap(from(m)));\n return ZERO;\n }\n\n /**\n * @notice Creates a signed fixed-decimal from a signed integer\n * @param a Signed number\n * @return New signed fixed-decimal\n */\n function from(int256 a) internal pure returns (Fixed18) {\n return Fixed18.wrap(a * BASE);\n }\n\n /**\n * @notice Creates a packed signed fixed-decimal from an signed fixed-decimal\n * @param a signed fixed-decimal\n * @return New packed signed fixed-decimal\n */\n function pack(Fixed18 a) internal pure returns (PackedFixed18) {\n int256 value = Fixed18.unwrap(a);\n if (value > type(int128).max) revert Fixed18PackingOverflowError(value);\n if (value < type(int128).min) revert Fixed18PackingUnderflowError(value);\n return PackedFixed18.wrap(int128(value));\n }\n\n /**\n * @notice Returns whether the signed fixed-decimal is equal to zero.\n * @param a Signed fixed-decimal\n * @return Whether the signed fixed-decimal is zero.\n */\n function isZero(Fixed18 a) internal pure returns (bool) {\n return Fixed18.unwrap(a) == 0;\n }\n\n /**\n * @notice Adds two signed fixed-decimals `a` and `b` together\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Resulting summed signed fixed-decimal\n */\n function add(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) + Fixed18.unwrap(b));\n }\n\n /**\n * @notice Subtracts signed fixed-decimal `b` from `a`\n * @param a Signed fixed-decimal to subtract from\n * @param b Signed fixed-decimal to subtract\n * @return Resulting subtracted signed fixed-decimal\n */\n function sub(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) - Fixed18.unwrap(b));\n }\n\n /**\n * @notice Multiplies two signed fixed-decimals `a` and `b` together\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Resulting multiplied signed fixed-decimal\n */\n function mul(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / BASE);\n }\n\n /**\n * @notice Divides signed fixed-decimal `a` by `b`\n * @param a Signed fixed-decimal to divide\n * @param b Signed fixed-decimal to divide by\n * @return Resulting divided signed fixed-decimal\n */\n function div(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) * BASE / Fixed18.unwrap(b));\n }\n\n /**\n * @notice Divides unsigned fixed-decimal `a` by `b`\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0`, `MAX` for `n/0`, and `MIN` for `-n/0`.\n * @param a Unsigned fixed-decimal to divide\n * @param b Unsigned fixed-decimal to divide by\n * @return Resulting divided unsigned fixed-decimal\n */\n function unsafeDiv(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n if (isZero(b)) {\n if (gt(a, ZERO)) return MAX;\n if (lt(a, ZERO)) return MIN;\n return ONE;\n } else {\n return div(a, b);\n }\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First signed fixed-decimal\n * @param b Signed number to multiply by\n * @param c Signed number to divide by\n * @return Resulting computation\n */\n function muldiv(Fixed18 a, int256 b, int256 c) internal pure returns (Fixed18) {\n return muldiv(a, Fixed18.wrap(b), Fixed18.wrap(c));\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First signed fixed-decimal\n * @param b Signed fixed-decimal to multiply by\n * @param c Signed fixed-decimal to divide by\n * @return Resulting computation\n */\n function muldiv(Fixed18 a, Fixed18 b, Fixed18 c) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / Fixed18.unwrap(c));\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is equal to `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is equal to `b`\n */\n function eq(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return compare(a, b) == 1;\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is greater than `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is greater than `b`\n */\n function gt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return compare(a, b) == 2;\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is less than `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is less than `b`\n */\n function lt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return compare(a, b) == 0;\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is greater than or equal to `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is greater than or equal to `b`\n */\n function gte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return gt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is less than or equal to `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is less than or equal to `b`\n */\n function lte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return lt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Compares the signed fixed-decimals `a` and `b`\n * @dev Returns: 2 for greater than\n * 1 for equal to\n * 0 for less than\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Compare result of `a` and `b`\n */\n function compare(Fixed18 a, Fixed18 b) internal pure returns (uint256) {\n (int256 au, int256 bu) = (Fixed18.unwrap(a), Fixed18.unwrap(b));\n if (au > bu) return 2;\n if (au < bu) return 0;\n return 1;\n }\n\n /**\n * @notice Returns a signed fixed-decimal representing the ratio of `a` over `b`\n * @param a First signed number\n * @param b Second signed number\n * @return Ratio of `a` over `b`\n */\n function ratio(int256 a, int256 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(a * BASE / b);\n }\n\n /**\n * @notice Returns the minimum of signed fixed-decimals `a` and `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Minimum of `a` and `b`\n */\n function min(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(SignedMath.min(Fixed18.unwrap(a), Fixed18.unwrap(b)));\n }\n\n /**\n * @notice Returns the maximum of signed fixed-decimals `a` and `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Maximum of `a` and `b`\n */\n function max(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(SignedMath.max(Fixed18.unwrap(a), Fixed18.unwrap(b)));\n }\n\n /**\n * @notice Converts the signed fixed-decimal into an integer, truncating any decimal portion\n * @param a Signed fixed-decimal\n * @return Truncated signed number\n */\n function truncate(Fixed18 a) internal pure returns (int256) {\n return Fixed18.unwrap(a) / BASE;\n }\n\n /**\n * @notice Returns the sign of the signed fixed-decimal\n * @dev Returns: -1 for negative\n * 0 for zero\n * 1 for positive\n * @param a Signed fixed-decimal\n * @return Sign of the signed fixed-decimal\n */\n function sign(Fixed18 a) internal pure returns (int256) {\n if (Fixed18.unwrap(a) > 0) return 1;\n if (Fixed18.unwrap(a) < 0) return -1;\n return 0;\n }\n\n /**\n * @notice Returns the absolute value of the signed fixed-decimal\n * @param a Signed fixed-decimal\n * @return Absolute value of the signed fixed-decimal\n */\n function abs(Fixed18 a) internal pure returns (UFixed18) {\n return UFixed18.wrap(SignedMath.abs(Fixed18.unwrap(a)));\n }\n}\n\nlibrary Fixed18StorageLib {\n function read(Fixed18Storage self) internal view returns (Fixed18 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(Fixed18Storage self, Fixed18 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/number/types/PackedFixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./Fixed18.sol\";\n\n/// @dev PackedFixed18 type\ntype PackedFixed18 is int128;\nusing PackedFixed18Lib for PackedFixed18 global;\n\n/**\n * @title PackedFixed18Lib\n * @dev A packed version of the Fixed18 which takes up half the storage space (two PackedFixed18 can be packed\n * into a single slot). Only valid within the range -1.7014118e+20 <= x <= 1.7014118e+20.\n * @notice Library for the packed signed fixed-decimal type.\n */\nlibrary PackedFixed18Lib {\n PackedFixed18 public constant MAX = PackedFixed18.wrap(type(int128).max);\n PackedFixed18 public constant MIN = PackedFixed18.wrap(type(int128).min);\n\n /**\n * @notice Creates an unpacked signed fixed-decimal from a packed signed fixed-decimal\n * @param self packed signed fixed-decimal\n * @return New unpacked signed fixed-decimal\n */\n function unpack(PackedFixed18 self) internal pure returns (Fixed18) {\n return Fixed18.wrap(int256(PackedFixed18.unwrap(self)));\n }\n}\n" + }, + "@equilibria/root/number/types/PackedUFixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./UFixed18.sol\";\n\n/// @dev PackedUFixed18 type\ntype PackedUFixed18 is uint128;\nusing PackedUFixed18Lib for PackedUFixed18 global;\n\n/**\n * @title PackedUFixed18Lib\n * @dev A packed version of the UFixed18 which takes up half the storage space (two PackedUFixed18 can be packed\n * into a single slot). Only valid within the range 0 <= x <= 3.4028237e+20.\n * @notice Library for the packed unsigned fixed-decimal type.\n */\nlibrary PackedUFixed18Lib {\n PackedUFixed18 public constant MAX = PackedUFixed18.wrap(type(uint128).max);\n\n /**\n * @notice Creates an unpacked unsigned fixed-decimal from a packed unsigned fixed-decimal\n * @param self packed unsigned fixed-decimal\n * @return New unpacked unsigned fixed-decimal\n */\n function unpack(PackedUFixed18 self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(PackedUFixed18.unwrap(self)));\n }\n}\n" + }, + "@equilibria/root/number/types/UFixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"./Fixed18.sol\";\nimport \"./PackedUFixed18.sol\";\n\n/// @dev UFixed18 type\ntype UFixed18 is uint256;\nusing UFixed18Lib for UFixed18 global;\ntype UFixed18Storage is bytes32;\nusing UFixed18StorageLib for UFixed18Storage global;\n\n/**\n * @title UFixed18Lib\n * @notice Library for the unsigned fixed-decimal type.\n */\nlibrary UFixed18Lib {\n error UFixed18UnderflowError(int256 value);\n error UFixed18PackingOverflowError(uint256 value);\n\n uint256 private constant BASE = 1e18;\n UFixed18 public constant ZERO = UFixed18.wrap(0);\n UFixed18 public constant ONE = UFixed18.wrap(BASE);\n UFixed18 public constant MAX = UFixed18.wrap(type(uint256).max);\n\n /**\n * @notice Creates a unsigned fixed-decimal from a signed fixed-decimal\n * @param a Signed fixed-decimal\n * @return New unsigned fixed-decimal\n */\n function from(Fixed18 a) internal pure returns (UFixed18) {\n int256 value = Fixed18.unwrap(a);\n if (value < 0) revert UFixed18UnderflowError(value);\n return UFixed18.wrap(uint256(value));\n }\n\n /**\n * @notice Creates a unsigned fixed-decimal from a unsigned integer\n * @param a Unsigned number\n * @return New unsigned fixed-decimal\n */\n function from(uint256 a) internal pure returns (UFixed18) {\n return UFixed18.wrap(a * BASE);\n }\n\n /**\n * @notice Creates a packed unsigned fixed-decimal from an unsigned fixed-decimal\n * @param a unsigned fixed-decimal\n * @return New packed unsigned fixed-decimal\n */\n function pack(UFixed18 a) internal pure returns (PackedUFixed18) {\n uint256 value = UFixed18.unwrap(a);\n if (value > type(uint128).max) revert UFixed18PackingOverflowError(value);\n return PackedUFixed18.wrap(uint128(value));\n }\n\n /**\n * @notice Returns whether the unsigned fixed-decimal is equal to zero.\n * @param a Unsigned fixed-decimal\n * @return Whether the unsigned fixed-decimal is zero.\n */\n function isZero(UFixed18 a) internal pure returns (bool) {\n return UFixed18.unwrap(a) == 0;\n }\n\n /**\n * @notice Adds two unsigned fixed-decimals `a` and `b` together\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Resulting summed unsigned fixed-decimal\n */\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n\n /**\n * @notice Subtracts unsigned fixed-decimal `b` from `a`\n * @param a Unsigned fixed-decimal to subtract from\n * @param b Unsigned fixed-decimal to subtract\n * @return Resulting subtracted unsigned fixed-decimal\n */\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n\n /**\n * @notice Multiplies two unsigned fixed-decimals `a` and `b` together\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Resulting multiplied unsigned fixed-decimal\n */\n function mul(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / BASE);\n }\n\n /**\n * @notice Divides unsigned fixed-decimal `a` by `b`\n * @param a Unsigned fixed-decimal to divide\n * @param b Unsigned fixed-decimal to divide by\n * @return Resulting divided unsigned fixed-decimal\n */\n function div(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) * BASE / UFixed18.unwrap(b));\n }\n\n /**\n * @notice Divides unsigned fixed-decimal `a` by `b`\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0` and `MAX` for `n/0`.\n * @param a Unsigned fixed-decimal to divide\n * @param b Unsigned fixed-decimal to divide by\n * @return Resulting divided unsigned fixed-decimal\n */\n function unsafeDiv(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n if (isZero(b)) {\n return isZero(a) ? ONE : MAX;\n } else {\n return div(a, b);\n }\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First unsigned fixed-decimal\n * @param b Unsigned number to multiply by\n * @param c Unsigned number to divide by\n * @return Resulting computation\n */\n function muldiv(UFixed18 a, uint256 b, uint256 c) internal pure returns (UFixed18) {\n return muldiv(a, UFixed18.wrap(b), UFixed18.wrap(c));\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First unsigned fixed-decimal\n * @param b Unsigned fixed-decimal to multiply by\n * @param c Unsigned fixed-decimal to divide by\n * @return Resulting computation\n */\n function muldiv(UFixed18 a, UFixed18 b, UFixed18 c) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / UFixed18.unwrap(c));\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is equal to `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is equal to `b`\n */\n function eq(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return compare(a, b) == 1;\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is greater than `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is greater than `b`\n */\n function gt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return compare(a, b) == 2;\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is less than `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is less than `b`\n */\n function lt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return compare(a, b) == 0;\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is greater than or equal to `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is greater than or equal to `b`\n */\n function gte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return gt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is less than or equal to `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is less than or equal to `b`\n */\n function lte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return lt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Compares the unsigned fixed-decimals `a` and `b`\n * @dev Returns: 2 for greater than\n * 1 for equal to\n * 0 for less than\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Compare result of `a` and `b`\n */\n function compare(UFixed18 a, UFixed18 b) internal pure returns (uint256) {\n (uint256 au, uint256 bu) = (UFixed18.unwrap(a), UFixed18.unwrap(b));\n if (au > bu) return 2;\n if (au < bu) return 0;\n return 1;\n }\n\n /**\n * @notice Returns a unsigned fixed-decimal representing the ratio of `a` over `b`\n * @param a First unsigned number\n * @param b Second unsigned number\n * @return Ratio of `a` over `b`\n */\n function ratio(uint256 a, uint256 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(a * BASE / b);\n }\n\n /**\n * @notice Returns the minimum of unsigned fixed-decimals `a` and `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Minimum of `a` and `b`\n */\n function min(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(Math.min(UFixed18.unwrap(a), UFixed18.unwrap(b)));\n }\n\n /**\n * @notice Returns the maximum of unsigned fixed-decimals `a` and `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Maximum of `a` and `b`\n */\n function max(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(Math.max(UFixed18.unwrap(a), UFixed18.unwrap(b)));\n }\n\n /**\n * @notice Converts the unsigned fixed-decimal into an integer, truncating any decimal portion\n * @param a Unsigned fixed-decimal\n * @return Truncated unsigned number\n */\n function truncate(UFixed18 a) internal pure returns (uint256) {\n return UFixed18.unwrap(a) / BASE;\n }\n}\n\nlibrary UFixed18StorageLib {\n function read(UFixed18Storage self) internal view returns (UFixed18 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(UFixed18Storage self, UFixed18 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/storage/UStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../number/types/UFixed18.sol\";\n\n/// @dev Stored boolean slot\ntype BoolStorage is bytes32;\nusing BoolStorageLib for BoolStorage global;\n\n/// @dev Stored uint256 slot\ntype Uint256Storage is bytes32;\nusing Uint256StorageLib for Uint256Storage global;\n\n/// @dev Stored int256 slot\ntype Int256Storage is bytes32;\nusing Int256StorageLib for Int256Storage global;\n\n/// @dev Stored address slot\ntype AddressStorage is bytes32;\nusing AddressStorageLib for AddressStorage global;\n\n/// @dev Stored bytes32 slot\ntype Bytes32Storage is bytes32;\nusing Bytes32StorageLib for Bytes32Storage global;\n\n/**\n * @title BoolStorageLib\n * @notice Library to manage storage and retrival of a boolean at a fixed storage slot\n */\nlibrary BoolStorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored bool value\n */\n function read(BoolStorage self) internal view returns (bool value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value boolean value to store\n */\n function store(BoolStorage self, bool value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title Uint256StorageLib\n * @notice Library to manage storage and retrival of an uint256 at a fixed storage slot\n */\nlibrary Uint256StorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored uint256 value\n */\n function read(Uint256Storage self) internal view returns (uint256 value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value uint256 value to store\n */\n function store(Uint256Storage self, uint256 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title Int256StorageLib\n * @notice Library to manage storage and retrival of an int256 at a fixed storage slot\n */\nlibrary Int256StorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored int256 value\n */\n function read(Int256Storage self) internal view returns (int256 value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value int256 value to store\n */\n function store(Int256Storage self, int256 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title AddressStorageLib\n * @notice Library to manage storage and retrival of an address at a fixed storage slot\n */\nlibrary AddressStorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored address value\n */\n function read(AddressStorage self) internal view returns (address value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value address value to store\n */\n function store(AddressStorage self, address value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title Bytes32StorageLib\n * @notice Library to manage storage and retrival of a bytes32 at a fixed storage slot\n */\nlibrary Bytes32StorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored bytes32 value\n */\n function read(Bytes32Storage self) internal view returns (bytes32 value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value bytes32 value to store\n */\n function store(Bytes32Storage self, bytes32 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/token/types/Token18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../../number/types/UFixed18.sol\";\n\n/// @dev Token18\ntype Token18 is address;\nusing Token18Lib for Token18 global;\ntype Token18Storage is bytes32;\nusing Token18StorageLib for Token18Storage global;\n\n/**\n * @title Token18Lib\n * @notice Library to manage 18-decimal ERC20s that is compliant with the fixed-decimal types.\n * @dev Maintains significant gas savings over other Token implementations since no conversion take place\n */\nlibrary Token18Lib {\n using SafeERC20 for IERC20;\n\n Token18 public constant ZERO = Token18.wrap(address(0));\n\n /**\n * @notice Returns whether a token is the zero address\n * @param self Token to check for\n * @return Whether the token is the zero address\n */\n function isZero(Token18 self) internal pure returns (bool) {\n return Token18.unwrap(self) == Token18.unwrap(ZERO);\n }\n\n /**\n * @notice Returns whether the two tokens are equal\n * @param a First token to compare\n * @param b Second token to compare\n * @return Whether the two tokens are equal\n */\n function eq(Token18 a, Token18 b) internal pure returns (bool) {\n return Token18.unwrap(a) == Token18.unwrap(b);\n }\n\n /**\n * @notice Approves `grantee` to spend infinite tokens from the caller\n * @param self Token to transfer\n * @param grantee Address to allow spending\n */\n function approve(Token18 self, address grantee) internal {\n IERC20(Token18.unwrap(self)).safeApprove(grantee, type(uint256).max);\n }\n\n /**\n * @notice Approves `grantee` to spend `amount` tokens from the caller\n * @dev There are important race conditions to be aware of when using this function\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\n * @param self Token to transfer\n * @param grantee Address to allow spending\n * @param amount Amount of tokens to approve to spend\n */\n function approve(Token18 self, address grantee, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeApprove(grantee, UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Transfers all held tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to receive the tokens\n */\n function push(Token18 self, address recipient) internal {\n push(self, recipient, balanceOf(self, address(this)));\n }\n\n /**\n * @notice Transfers `amount` tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function push(Token18 self, address recipient, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeTransfer(recipient, UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param amount Amount of tokens to transfer\n */\n function pull(Token18 self, address benefactor, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, address(this), UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function pullTo(Token18 self, address benefactor, address recipient, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, recipient, UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Returns the name of the token\n * @param self Token to check for\n * @return Token name\n */\n function name(Token18 self) internal view returns (string memory) {\n return IERC20Metadata(Token18.unwrap(self)).name();\n }\n\n /**\n * @notice Returns the symbol of the token\n * @param self Token to check for\n * @return Token symbol\n */\n function symbol(Token18 self) internal view returns (string memory) {\n return IERC20Metadata(Token18.unwrap(self)).symbol();\n }\n\n /**\n * @notice Returns the `self` token balance of the caller\n * @param self Token to check for\n * @return Token balance of the caller\n */\n function balanceOf(Token18 self) internal view returns (UFixed18) {\n return balanceOf(self, address(this));\n }\n\n /**\n * @notice Returns the `self` token balance of `account`\n * @param self Token to check for\n * @param account Account to check\n * @return Token balance of the account\n */\n function balanceOf(Token18 self, address account) internal view returns (UFixed18) {\n return UFixed18.wrap(IERC20(Token18.unwrap(self)).balanceOf(account));\n }\n}\n\nlibrary Token18StorageLib {\n function read(Token18Storage self) internal view returns (Token18 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(Token18Storage self, Token18 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/token/types/Token6.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"../../number/types/UFixed18.sol\";\n\n/// @dev Token6\ntype Token6 is address;\nusing Token6Lib for Token6 global;\ntype Token6Storage is bytes32;\nusing Token6StorageLib for Token6Storage global;\n\n/**\n * @title Token6Lib\n * @notice Library to manage 6-decimal ERC20s that is compliant with the fixed-decimal types.\n * @dev Automatically converts from Base-6 token amounts to Base-18 UFixed18 amounts, with optional rounding\n */\nlibrary Token6Lib {\n using SafeERC20 for IERC20;\n\n Token6 public constant ZERO = Token6.wrap(address(0));\n\n uint256 private constant OFFSET = 1e12;\n\n /**\n * @notice Returns whether a token is the zero address\n * @param self Token to check for\n * @return Whether the token is the zero address\n */\n function isZero(Token6 self) internal pure returns (bool) {\n return Token6.unwrap(self) == Token6.unwrap(ZERO);\n }\n\n /**\n * @notice Returns whether the two tokens are equal\n * @param a First token to compare\n * @param b Second token to compare\n * @return Whether the two tokens are equal\n */\n function eq(Token6 a, Token6 b) internal pure returns (bool) {\n return Token6.unwrap(a) == Token6.unwrap(b);\n }\n\n /**\n * @notice Approves `grantee` to spend infinite tokens from the caller\n * @param self Token to transfer\n * @param grantee Address to allow spending\n */\n function approve(Token6 self, address grantee) internal {\n IERC20(Token6.unwrap(self)).safeApprove(grantee, type(uint256).max);\n }\n\n /**\n * @notice Approves `grantee` to spend `amount` tokens from the caller\n * @dev There are important race conditions to be aware of when using this function\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\n * @param self Token to transfer\n * @param grantee Address to allow spending\n * @param amount Amount of tokens to approve to spend\n */\n function approve(Token6 self, address grantee, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, false));\n }\n\n /**\n * @notice Approves `grantee` to spend `amount` tokens from the caller\n * @dev There are important race conditions to be aware of when using this function\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\n * @param self Token to transfer\n * @param grantee Address to allow spending\n * @param amount Amount of tokens to approve to spend\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function approve(Token6 self, address grantee, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Transfers all held tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to receive the tokens\n */\n function push(Token6 self, address recipient) internal {\n push(self, recipient, balanceOf(self, address(this)));\n }\n\n /**\n * @notice Transfers `amount` tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function push(Token6 self, address recipient, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, false));\n }\n\n /**\n * @notice Transfers `amount` tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function push(Token6 self, address recipient, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param amount Amount of tokens to transfer\n */\n function pull(Token6 self, address benefactor, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, false));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param amount Amount of tokens to transfer\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function pull(Token6 self, address benefactor, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, false));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Returns the name of the token\n * @param self Token to check for\n * @return Token name\n */\n function name(Token6 self) internal view returns (string memory) {\n return IERC20Metadata(Token6.unwrap(self)).name();\n }\n\n /**\n * @notice Returns the symbol of the token\n * @param self Token to check for\n * @return Token symbol\n */\n function symbol(Token6 self) internal view returns (string memory) {\n return IERC20Metadata(Token6.unwrap(self)).symbol();\n }\n\n /**\n * @notice Returns the `self` token balance of the caller\n * @param self Token to check for\n * @return Token balance of the caller\n */\n function balanceOf(Token6 self) internal view returns (UFixed18) {\n return balanceOf(self, address(this));\n }\n\n /**\n * @notice Returns the `self` token balance of `account`\n * @param self Token to check for\n * @param account Account to check\n * @return Token balance of the account\n */\n function balanceOf(Token6 self, address account) internal view returns (UFixed18) {\n return fromTokenAmount(IERC20(Token6.unwrap(self)).balanceOf(account));\n }\n\n /**\n * @notice Converts the unsigned fixed-decimal amount into the token amount according to\n * it's defined decimals\n * @dev Provides the ability to \"round up\" the token amount which is useful in situations where\n * are swapping one token for another and don't want to give away \"free\" units due to rounding\n * errors in the favor of the user.\n * @param amount Amount to convert\n * @param roundUp Whether to round decimal token amount up to the next unit\n * @return Normalized token amount\n */\n function toTokenAmount(UFixed18 amount, bool roundUp) private pure returns (uint256) {\n return roundUp ? Math.ceilDiv(UFixed18.unwrap(amount), OFFSET) : UFixed18.unwrap(amount) / OFFSET;\n }\n\n /**\n * @notice Converts the token amount into the unsigned fixed-decimal amount according to\n * it's defined decimals\n * @param amount Token amount to convert\n * @return Normalized unsigned fixed-decimal amount\n */\n function fromTokenAmount(uint256 amount) private pure returns (UFixed18) {\n return UFixed18.wrap(amount * OFFSET);\n }\n}\n\nlibrary Token6StorageLib {\n function read(Token6Storage self) internal view returns (Token6 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(Token6Storage self, Token6 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(uint160(account), 20),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/AccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerable.sol\";\nimport \"./AccessControl.sol\";\nimport \"../utils/structs/EnumerableSet.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol)\n\npragma solidity ^0.8.4;\n\nimport \"../CrossChainEnabled.sol\";\nimport \"./LibArbitrumL2.sol\";\n\n/**\n * @dev [Arbitrum](https://arbitrum.io/) specialization or the\n * {CrossChainEnabled} abstraction the L2 side (arbitrum).\n *\n * This version should only be deployed on L2 to process cross-chain messages\n * originating from L1. For the other side, use {CrossChainEnabledArbitrumL1}.\n *\n * Arbitrum L2 includes the `ArbSys` contract at a fixed address. Therefore,\n * this specialization of {CrossChainEnabled} does not include a constructor.\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabledArbitrumL2 is CrossChainEnabled {\n /**\n * @dev see {CrossChainEnabled-_isCrossChain}\n */\n function _isCrossChain() internal view virtual override returns (bool) {\n return LibArbitrumL2.isCrossChain(LibArbitrumL2.ARBSYS);\n }\n\n /**\n * @dev see {CrossChainEnabled-_crossChainSender}\n */\n function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {\n return LibArbitrumL2.crossChainSender(LibArbitrumL2.ARBSYS);\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/arbitrum/LibArbitrumL2.sol)\n\npragma solidity ^0.8.4;\n\nimport {IArbSys as ArbitrumL2_Bridge} from \"../../vendor/arbitrum/IArbSys.sol\";\nimport \"../errors.sol\";\n\n/**\n * @dev Primitives for cross-chain aware contracts for\n * [Arbitrum](https://arbitrum.io/).\n *\n * This version should only be used on L2 to process cross-chain messages\n * originating from L1. For the other side, use {LibArbitrumL1}.\n */\nlibrary LibArbitrumL2 {\n /**\n * @dev Returns whether the current function call is the result of a\n * cross-chain message relayed by `arbsys`.\n */\n address public constant ARBSYS = 0x0000000000000000000000000000000000000064;\n\n function isCrossChain(address arbsys) internal view returns (bool) {\n return ArbitrumL2_Bridge(arbsys).isTopLevelCall();\n }\n\n /**\n * @dev Returns the address of the sender that triggered the current\n * cross-chain message through `arbsys`.\n *\n * NOTE: {isCrossChain} should be checked before trying to recover the\n * sender, as it will revert with `NotCrossChainCall` if the current\n * function call is not the result of a cross-chain message.\n */\n function crossChainSender(address arbsys) internal view returns (address) {\n if (!isCrossChain(arbsys)) revert NotCrossChainCall();\n\n return\n ArbitrumL2_Bridge(arbsys).wasMyCallersAddressAliased()\n ? ArbitrumL2_Bridge(arbsys).myCallersAddressWithoutAliasing()\n : msg.sender;\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/CrossChainEnabled.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/CrossChainEnabled.sol)\n\npragma solidity ^0.8.4;\n\nimport \"./errors.sol\";\n\n/**\n * @dev Provides information for building cross-chain aware contracts. This\n * abstract contract provides accessors and modifiers to control the execution\n * flow when receiving cross-chain messages.\n *\n * Actual implementations of cross-chain aware contracts, which are based on\n * this abstraction, will have to inherit from a bridge-specific\n * specialization. Such specializations are provided under\n * `crosschain//CrossChainEnabled.sol`.\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabled {\n /**\n * @dev Throws if the current function call is not the result of a\n * cross-chain execution.\n */\n modifier onlyCrossChain() {\n if (!_isCrossChain()) revert NotCrossChainCall();\n _;\n }\n\n /**\n * @dev Throws if the current function call is not the result of a\n * cross-chain execution initiated by `account`.\n */\n modifier onlyCrossChainSender(address expected) {\n address actual = _crossChainSender();\n if (expected != actual) revert InvalidCrossChainSender(actual, expected);\n _;\n }\n\n /**\n * @dev Returns whether the current function call is the result of a\n * cross-chain message.\n */\n function _isCrossChain() internal view virtual returns (bool);\n\n /**\n * @dev Returns the address of the sender of the cross-chain message that\n * triggered the current function call.\n *\n * IMPORTANT: Should revert with `NotCrossChainCall` if the current function\n * call is not the result of a cross-chain message.\n */\n function _crossChainSender() internal view virtual returns (address);\n}\n" + }, + "@openzeppelin/contracts/crosschain/errors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol)\n\npragma solidity ^0.8.4;\n\nerror NotCrossChainCall();\nerror InvalidCrossChainSender(address actual, address expected);\n" + }, + "@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/optimism/CrossChainEnabledOptimism.sol)\n\npragma solidity ^0.8.4;\n\nimport \"../CrossChainEnabled.sol\";\nimport \"./LibOptimism.sol\";\n\n/**\n * @dev [Optimism](https://www.optimism.io/) specialization or the\n * {CrossChainEnabled} abstraction.\n *\n * The messenger (`CrossDomainMessenger`) contract is provided and maintained by\n * the optimism team. You can find the address of this contract on mainnet and\n * kovan in the [deployments section of Optimism monorepo](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/deployments).\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabledOptimism is CrossChainEnabled {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address private immutable _messenger;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(address messenger) {\n _messenger = messenger;\n }\n\n /**\n * @dev see {CrossChainEnabled-_isCrossChain}\n */\n function _isCrossChain() internal view virtual override returns (bool) {\n return LibOptimism.isCrossChain(_messenger);\n }\n\n /**\n * @dev see {CrossChainEnabled-_crossChainSender}\n */\n function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {\n return LibOptimism.crossChainSender(_messenger);\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/optimism/LibOptimism.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/optimism/LibOptimism.sol)\n\npragma solidity ^0.8.4;\n\nimport {ICrossDomainMessenger as Optimism_Bridge} from \"../../vendor/optimism/ICrossDomainMessenger.sol\";\nimport \"../errors.sol\";\n\n/**\n * @dev Primitives for cross-chain aware contracts for [Optimism](https://www.optimism.io/).\n * See the [documentation](https://community.optimism.io/docs/developers/bridge/messaging/#accessing-msg-sender)\n * for the functionality used here.\n */\nlibrary LibOptimism {\n /**\n * @dev Returns whether the current function call is the result of a\n * cross-chain message relayed by `messenger`.\n */\n function isCrossChain(address messenger) internal view returns (bool) {\n return msg.sender == messenger;\n }\n\n /**\n * @dev Returns the address of the sender that triggered the current\n * cross-chain message through `messenger`.\n *\n * NOTE: {isCrossChain} should be checked before trying to recover the\n * sender, as it will revert with `NotCrossChainCall` if the current\n * function call is not the result of a cross-chain message.\n */\n function crossChainSender(address messenger) internal view returns (address) {\n if (!isCrossChain(messenger)) revert NotCrossChainCall();\n\n return Optimism_Bridge(messenger).xDomainMessageSender();\n }\n}\n" + }, + "@openzeppelin/contracts/governance/TimelockController.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (governance/TimelockController.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../access/AccessControl.sol\";\nimport \"../token/ERC721/IERC721Receiver.sol\";\nimport \"../token/ERC1155/IERC1155Receiver.sol\";\n\n/**\n * @dev Contract module which acts as a timelocked controller. When set as the\n * owner of an `Ownable` smart contract, it enforces a timelock on all\n * `onlyOwner` maintenance operations. This gives time for users of the\n * controlled contract to exit before a potentially dangerous maintenance\n * operation is applied.\n *\n * By default, this contract is self administered, meaning administration tasks\n * have to go through the timelock process. The proposer (resp executor) role\n * is in charge of proposing (resp executing) operations. A common use case is\n * to position this {TimelockController} as the owner of a smart contract, with\n * a multisig or a DAO as the sole proposer.\n *\n * _Available since v3.3._\n */\ncontract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver {\n bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256(\"TIMELOCK_ADMIN_ROLE\");\n bytes32 public constant PROPOSER_ROLE = keccak256(\"PROPOSER_ROLE\");\n bytes32 public constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n bytes32 public constant CANCELLER_ROLE = keccak256(\"CANCELLER_ROLE\");\n uint256 internal constant _DONE_TIMESTAMP = uint256(1);\n\n mapping(bytes32 => uint256) private _timestamps;\n uint256 private _minDelay;\n\n /**\n * @dev Emitted when a call is scheduled as part of operation `id`.\n */\n event CallScheduled(\n bytes32 indexed id,\n uint256 indexed index,\n address target,\n uint256 value,\n bytes data,\n bytes32 predecessor,\n uint256 delay\n );\n\n /**\n * @dev Emitted when a call is performed as part of operation `id`.\n */\n event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);\n\n /**\n * @dev Emitted when operation `id` is cancelled.\n */\n event Cancelled(bytes32 indexed id);\n\n /**\n * @dev Emitted when the minimum delay for future operations is modified.\n */\n event MinDelayChange(uint256 oldDuration, uint256 newDuration);\n\n /**\n * @dev Initializes the contract with a given `minDelay`, and a list of\n * initial proposers and executors. The proposers receive both the\n * proposer and the canceller role (for backward compatibility). The\n * executors receive the executor role.\n *\n * NOTE: At construction, both the deployer and the timelock itself are\n * administrators. This helps further configuration of the timelock by the\n * deployer. After configuration is done, it is recommended that the\n * deployer renounces its admin position and relies on timelocked\n * operations to perform future maintenance.\n */\n constructor(\n uint256 minDelay,\n address[] memory proposers,\n address[] memory executors\n ) {\n _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE);\n\n // deployer + self administration\n _setupRole(TIMELOCK_ADMIN_ROLE, _msgSender());\n _setupRole(TIMELOCK_ADMIN_ROLE, address(this));\n\n // register proposers and cancellers\n for (uint256 i = 0; i < proposers.length; ++i) {\n _setupRole(PROPOSER_ROLE, proposers[i]);\n _setupRole(CANCELLER_ROLE, proposers[i]);\n }\n\n // register executors\n for (uint256 i = 0; i < executors.length; ++i) {\n _setupRole(EXECUTOR_ROLE, executors[i]);\n }\n\n _minDelay = minDelay;\n emit MinDelayChange(0, minDelay);\n }\n\n /**\n * @dev Modifier to make a function callable only by a certain role. In\n * addition to checking the sender's role, `address(0)` 's role is also\n * considered. Granting a role to `address(0)` is equivalent to enabling\n * this role for everyone.\n */\n modifier onlyRoleOrOpenRole(bytes32 role) {\n if (!hasRole(role, address(0))) {\n _checkRole(role, _msgSender());\n }\n _;\n }\n\n /**\n * @dev Contract might receive/hold ETH as part of the maintenance process.\n */\n receive() external payable {}\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, AccessControl) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns whether an id correspond to a registered operation. This\n * includes both Pending, Ready and Done operations.\n */\n function isOperation(bytes32 id) public view virtual returns (bool pending) {\n return getTimestamp(id) > 0;\n }\n\n /**\n * @dev Returns whether an operation is pending or not.\n */\n function isOperationPending(bytes32 id) public view virtual returns (bool pending) {\n return getTimestamp(id) > _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Returns whether an operation is ready or not.\n */\n function isOperationReady(bytes32 id) public view virtual returns (bool ready) {\n uint256 timestamp = getTimestamp(id);\n return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;\n }\n\n /**\n * @dev Returns whether an operation is done or not.\n */\n function isOperationDone(bytes32 id) public view virtual returns (bool done) {\n return getTimestamp(id) == _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Returns the timestamp at with an operation becomes ready (0 for\n * unset operations, 1 for done operations).\n */\n function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {\n return _timestamps[id];\n }\n\n /**\n * @dev Returns the minimum delay for an operation to become valid.\n *\n * This value can be changed by executing an operation that calls `updateDelay`.\n */\n function getMinDelay() public view virtual returns (uint256 duration) {\n return _minDelay;\n }\n\n /**\n * @dev Returns the identifier of an operation containing a single\n * transaction.\n */\n function hashOperation(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt\n ) public pure virtual returns (bytes32 hash) {\n return keccak256(abi.encode(target, value, data, predecessor, salt));\n }\n\n /**\n * @dev Returns the identifier of an operation containing a batch of\n * transactions.\n */\n function hashOperationBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt\n ) public pure virtual returns (bytes32 hash) {\n return keccak256(abi.encode(targets, values, payloads, predecessor, salt));\n }\n\n /**\n * @dev Schedule an operation containing a single transaction.\n *\n * Emits a {CallScheduled} event.\n *\n * Requirements:\n *\n * - the caller must have the 'proposer' role.\n */\n function schedule(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt,\n uint256 delay\n ) public virtual onlyRole(PROPOSER_ROLE) {\n bytes32 id = hashOperation(target, value, data, predecessor, salt);\n _schedule(id, delay);\n emit CallScheduled(id, 0, target, value, data, predecessor, delay);\n }\n\n /**\n * @dev Schedule an operation containing a batch of transactions.\n *\n * Emits one {CallScheduled} event per transaction in the batch.\n *\n * Requirements:\n *\n * - the caller must have the 'proposer' role.\n */\n function scheduleBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt,\n uint256 delay\n ) public virtual onlyRole(PROPOSER_ROLE) {\n require(targets.length == values.length, \"TimelockController: length mismatch\");\n require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n _schedule(id, delay);\n for (uint256 i = 0; i < targets.length; ++i) {\n emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);\n }\n }\n\n /**\n * @dev Schedule an operation that is to becomes valid after a given delay.\n */\n function _schedule(bytes32 id, uint256 delay) private {\n require(!isOperation(id), \"TimelockController: operation already scheduled\");\n require(delay >= getMinDelay(), \"TimelockController: insufficient delay\");\n _timestamps[id] = block.timestamp + delay;\n }\n\n /**\n * @dev Cancel an operation.\n *\n * Requirements:\n *\n * - the caller must have the 'canceller' role.\n */\n function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {\n require(isOperationPending(id), \"TimelockController: operation cannot be cancelled\");\n delete _timestamps[id];\n\n emit Cancelled(id);\n }\n\n /**\n * @dev Execute an (ready) operation containing a single transaction.\n *\n * Emits a {CallExecuted} event.\n *\n * Requirements:\n *\n * - the caller must have the 'executor' role.\n */\n // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n // thus any modifications to the operation during reentrancy should be caught.\n // slither-disable-next-line reentrancy-eth\n function execute(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt\n ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n bytes32 id = hashOperation(target, value, data, predecessor, salt);\n _beforeCall(id, predecessor);\n _call(id, 0, target, value, data);\n _afterCall(id);\n }\n\n /**\n * @dev Execute an (ready) operation containing a batch of transactions.\n *\n * Emits one {CallExecuted} event per transaction in the batch.\n *\n * Requirements:\n *\n * - the caller must have the 'executor' role.\n */\n function executeBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt\n ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n require(targets.length == values.length, \"TimelockController: length mismatch\");\n require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n _beforeCall(id, predecessor);\n for (uint256 i = 0; i < targets.length; ++i) {\n _call(id, i, targets[i], values[i], payloads[i]);\n }\n _afterCall(id);\n }\n\n /**\n * @dev Checks before execution of an operation's calls.\n */\n function _beforeCall(bytes32 id, bytes32 predecessor) private view {\n require(isOperationReady(id), \"TimelockController: operation is not ready\");\n require(predecessor == bytes32(0) || isOperationDone(predecessor), \"TimelockController: missing dependency\");\n }\n\n /**\n * @dev Checks after execution of an operation's calls.\n */\n function _afterCall(bytes32 id) private {\n require(isOperationReady(id), \"TimelockController: operation is not ready\");\n _timestamps[id] = _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Execute an operation's call.\n *\n * Emits a {CallExecuted} event.\n */\n function _call(\n bytes32 id,\n uint256 index,\n address target,\n uint256 value,\n bytes calldata data\n ) private {\n (bool success, ) = target.call{value: value}(data);\n require(success, \"TimelockController: underlying transaction reverted\");\n\n emit CallExecuted(id, index, target, value, data);\n }\n\n /**\n * @dev Changes the minimum timelock duration for future operations.\n *\n * Emits a {MinDelayChange} event.\n *\n * Requirements:\n *\n * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing\n * an operation where the timelock is the target and the data is the ABI-encoded call to this function.\n */\n function updateDelay(uint256 newDelay) external virtual {\n require(msg.sender == address(this), \"TimelockController: caller must be timelock\");\n emit MinDelayChange(_minDelay, newDelay);\n _minDelay = newDelay;\n }\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155Received}.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n assert(_BEACON_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.beacon\")) - 1));\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n constructor(address implementation_) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../security/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetMinterPauser.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../extensions/ERC20Burnable.sol\";\nimport \"../extensions/ERC20Pausable.sol\";\nimport \"../../../access/AccessControlEnumerable.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev {ERC20} token, including:\n *\n * - ability for holders to burn (destroy) their tokens\n * - a minter role that allows for token minting (creation)\n * - a pauser role that allows to stop all token transfers\n *\n * This contract uses {AccessControl} to lock permissioned functions using the\n * different roles - head to its documentation for details.\n *\n * The account that deploys the contract will be granted the minter and pauser\n * roles, as well as the default admin role, which will let it grant both minter\n * and pauser roles to other accounts.\n *\n * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._\n */\ncontract ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable {\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n /**\n * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the\n * account that deploys the contract.\n *\n * See {ERC20-constructor}.\n */\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n\n _setupRole(MINTER_ROLE, _msgSender());\n _setupRole(PAUSER_ROLE, _msgSender());\n }\n\n /**\n * @dev Creates `amount` new tokens for `to`.\n *\n * See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the `MINTER_ROLE`.\n */\n function mint(address to, uint256 amount) public virtual {\n require(hasRole(MINTER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have minter role to mint\");\n _mint(to, amount);\n }\n\n /**\n * @dev Pauses all token transfers.\n *\n * See {ERC20Pausable} and {Pausable-_pause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function pause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have pauser role to pause\");\n _pause();\n }\n\n /**\n * @dev Unpauses all token transfers.\n *\n * See {ERC20Pausable} and {Pausable-_unpause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function unpause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have pauser role to unpause\");\n _unpause();\n }\n\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20, ERC20Pausable) {\n super._beforeTokenTransfer(from, to, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/vendor/arbitrum/IArbSys.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IArbSys.sol)\npragma solidity >=0.4.21 <0.9.0;\n\n/**\n * @title Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality.\n */\ninterface IArbSys {\n /**\n * @notice Get internal version number identifying an ArbOS build\n * @return version number as int\n */\n function arbOSVersion() external pure returns (uint256);\n\n function arbChainID() external view returns (uint256);\n\n /**\n * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)\n * @return block number as int\n */\n function arbBlockNumber() external view returns (uint256);\n\n /**\n * @notice Send given amount of Eth to dest from sender.\n * This is a convenience function, which is equivalent to calling sendTxToL1 with empty calldataForL1.\n * @param destination recipient address on L1\n * @return unique identifier for this L2-to-L1 transaction.\n */\n function withdrawEth(address destination) external payable returns (uint256);\n\n /**\n * @notice Send a transaction to L1\n * @param destination recipient address on L1\n * @param calldataForL1 (optional) calldata for L1 contract call\n * @return a unique identifier for this L2-to-L1 transaction.\n */\n function sendTxToL1(address destination, bytes calldata calldataForL1) external payable returns (uint256);\n\n /**\n * @notice get the number of transactions issued by the given external account or the account sequence number of the given contract\n * @param account target account\n * @return the number of transactions issued by the given external account or the account sequence number of the given contract\n */\n function getTransactionCount(address account) external view returns (uint256);\n\n /**\n * @notice get the value of target L2 storage slot\n * This function is only callable from address 0 to prevent contracts from being able to call it\n * @param account target account\n * @param index target index of storage slot\n * @return stotage value for the given account at the given index\n */\n function getStorageAt(address account, uint256 index) external view returns (uint256);\n\n /**\n * @notice check if current call is coming from l1\n * @return true if the caller of this was called directly from L1\n */\n function isTopLevelCall() external view returns (bool);\n\n /**\n * @notice check if the caller (of this caller of this) is an aliased L1 contract address\n * @return true iff the caller's address is an alias for an L1 contract address\n */\n function wasMyCallersAddressAliased() external view returns (bool);\n\n /**\n * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing\n * @return address of the caller's caller, without applying L1 contract address aliasing\n */\n function myCallersAddressWithoutAliasing() external view returns (address);\n\n /**\n * @notice map L1 sender contract address to its L2 alias\n * @param sender sender address\n * @param dest destination address\n * @return aliased sender address\n */\n function mapL1SenderContractAddressToL2Alias(address sender, address dest) external pure returns (address);\n\n /**\n * @notice get the caller's amount of available storage gas\n * @return amount of storage gas available to the caller\n */\n function getStorageGasAvailable() external view returns (uint256);\n\n event L2ToL1Transaction(\n address caller,\n address indexed destination,\n uint256 indexed uniqueId,\n uint256 indexed batchNumber,\n uint256 indexInBatch,\n uint256 arbBlockNum,\n uint256 ethBlockNum,\n uint256 timestamp,\n uint256 callvalue,\n bytes data\n );\n}\n" + }, + "@openzeppelin/contracts/vendor/optimism/ICrossDomainMessenger.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (vendor/optimism/ICrossDomainMessenger.sol)\npragma solidity >0.5.0 <0.9.0;\n\n/**\n * @title ICrossDomainMessenger\n */\ninterface ICrossDomainMessenger {\n /**********\n * Events *\n **********/\n\n event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /*************\n * Variables *\n *************/\n\n function xDomainMessageSender() external view returns (address);\n\n /********************\n * Public Functions *\n ********************/\n\n /**\n * Sends a cross domain message to the target messenger.\n * @param _target Target contract address.\n * @param _message Message to send to the target.\n * @param _gasLimit Gas limit for the provided message.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _gasLimit\n ) external;\n}\n" + }, + "contracts/collateral/Collateral.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/root/control/unstructured/UReentrancyGuard.sol\";\nimport \"../interfaces/ICollateral.sol\";\nimport \"./types/OptimisticLedger.sol\";\nimport \"../controller/UControllerProvider.sol\";\n\n/**\n * @title Collateral\n * @notice Manages logic and state for all collateral accounts in the protocol.\n */\ncontract Collateral is ICollateral, UInitializable, UControllerProvider, UReentrancyGuard {\n /// @dev ERC20 stablecoin for collateral\n Token18 public immutable token;\n\n /// @dev Per product collateral state\n mapping(IProduct => OptimisticLedger) private _products;\n\n /// @dev Protocol and product fees collected, but not yet claimed\n mapping(address => UFixed18) public fees;\n\n /**\n * @notice Initializes the immutable contract state\n * @dev Called at implementation instantiate and constant for that implementation.\n * @param token_ Collateral ERC20 stablecoin address\n */\n constructor(Token18 token_) {\n token = token_;\n }\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n * @param controller_ Factory contract address\n */\n function initialize(IController controller_) external initializer(1) {\n __UControllerProvider__initialize(controller_);\n __UReentrancyGuard__initialize();\n }\n\n /**\n * @notice Deposits `amount` collateral from `msg.sender` to `account`'s `product`\n * account\n * @param account Account to deposit the collateral for\n * @param product Product to credit the collateral to\n * @param amount Amount of collateral to deposit\n */\n function depositTo(address account, IProduct product, UFixed18 amount)\n external\n nonReentrant\n notPaused\n notZeroAddress(account)\n isProduct(product)\n collateralInvariant(account, product)\n {\n _products[product].creditAccount(account, amount);\n token.pull(msg.sender, amount);\n\n emit Deposit(account, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` collateral from `msg.sender`'s `product` account\n * and sends it to `receiver`\n * @param receiver Account to withdraw the collateral to\n * @param product Product to withdraw the collateral from\n * @param amount Amount of collateral to withdraw\n */\n function withdrawTo(address receiver, IProduct product, UFixed18 amount) external {\n withdrawFrom(msg.sender, receiver, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` collateral from `account`'s `product` account\n * and sends it to `receiver`\n * @param account Account to withdraw the collateral from\n * @param receiver Account to withdraw the collateral to\n * @param product Product to withdraw the collateral from\n * @param amount Amount of collateral to withdraw\n */\n function withdrawFrom(address account, address receiver, IProduct product, UFixed18 amount)\n public\n nonReentrant\n notPaused\n notZeroAddress(receiver)\n isProduct(product)\n onlyAccountOrMultiInvoker(account)\n settleForAccount(account, product)\n collateralInvariant(account, product)\n maintenanceInvariant(account, product)\n {\n amount = amount.eq(UFixed18Lib.MAX) ? collateral(account, product) : amount;\n _products[product].debitAccount(account, amount);\n token.push(receiver, amount);\n\n emit Withdrawal(account, product, amount);\n }\n\n /**\n * @notice Liquidates `account`'s `product` collateral account\n * @dev Account must be under-collateralized, fee returned immediately to `msg.sender`\n * @param account Account to liquidate\n * @param product Product to liquidate for\n */\n function liquidate(address account, IProduct product)\n external\n nonReentrant\n notPaused\n isProduct(product)\n settleForAccount(account, product)\n {\n if (product.isLiquidating(account)) revert CollateralAccountLiquidatingError(account);\n\n UFixed18 totalMaintenance = product.maintenance(account);\n UFixed18 totalCollateral = collateral(account, product);\n\n if (!totalMaintenance.gt(totalCollateral))\n revert CollateralCantLiquidate(totalMaintenance, totalCollateral);\n\n product.closeAll(account);\n\n // claim fee\n UFixed18 liquidationFee = controller().liquidationFee();\n // If maintenance is less than minCollateral, use minCollateral for fee amount\n UFixed18 collateralForFee = UFixed18Lib.max(totalMaintenance, controller().minCollateral());\n UFixed18 fee = UFixed18Lib.min(totalCollateral, collateralForFee.mul(liquidationFee));\n\n _products[product].debitAccount(account, fee);\n token.push(msg.sender, fee);\n\n emit Liquidation(account, product, msg.sender, fee);\n }\n\n /**\n * @notice Credits `amount` to `account`'s collateral account\n * @dev Callable only by the corresponding product as part of the settlement flywheel.\n * Moves collateral within a product, any collateral leaving the product due to\n * fees has already been accounted for in the settleProduct flywheel.\n * Debits in excess of the account balance get recorded as shortfall, and can be\n * resolved by the product owner as needed.\n * @param account Account to credit\n * @param amount Amount to credit the account (can be negative)\n */\n function settleAccount(address account, Fixed18 amount) external onlyProduct {\n IProduct product = IProduct(msg.sender);\n\n UFixed18 newShortfall = _products[product].settleAccount(account, amount);\n\n emit AccountSettle(product, account, amount, newShortfall);\n }\n\n /**\n * @notice Debits `amount` from product's total collateral account\n * @dev Callable only by the corresponding product as part of the settlement flywheel\n * Removes collateral from the product as fees.\n * @param amount Amount to debit from the account\n */\n function settleProduct(UFixed18 amount) external onlyProduct {\n (IProduct product, IController controller) = (IProduct(msg.sender), controller());\n\n address protocolTreasury = controller.treasury();\n address productTreasury = controller.treasury(product);\n\n UFixed18 protocolFee = amount.mul(controller.protocolFee());\n UFixed18 productFee = amount.sub(protocolFee);\n\n _products[product].debit(amount);\n fees[protocolTreasury] = fees[protocolTreasury].add(protocolFee);\n fees[productTreasury] = fees[productTreasury].add(productFee);\n\n emit ProductSettle(product, protocolFee, productFee);\n }\n\n /**\n * @notice Returns the balance of `account`'s `product` collateral account\n * @param account Account to return for\n * @param product Product to return for\n * @return The balance of the collateral account\n */\n function collateral(address account, IProduct product) public view returns (UFixed18) {\n return _products[product].balances[account];\n }\n\n /**\n * @notice Returns the total balance of `product`'s collateral\n * @param product Product to return for\n * @return The total balance of collateral in the product\n */\n function collateral(IProduct product) external view returns (UFixed18) {\n return _products[product].total;\n }\n\n /**\n * @notice Returns the current shortfall of `product`'s collateral\n * @param product Product to return for\n * @return The current shortfall of the product\n */\n function shortfall(IProduct product) external view returns (UFixed18) {\n return _products[product].shortfall;\n }\n\n /**\n * @notice Returns whether `account`'s `product` collateral account can be liquidated\n * @param account Account to return for\n * @param product Product to return for\n * @return Whether the account can be liquidated\n */\n function liquidatable(address account, IProduct product) external view returns (bool) {\n if (product.isLiquidating(account)) return false;\n\n return product.maintenance(account).gt(collateral(account, product));\n }\n\n /**\n * @notice Returns whether `account`'s `product` collateral account can be liquidated\n * after the next oracle version settlement\n * @dev Takes into account the current pre-position on the account\n * @param account Account to return for\n * @param product Product to return for\n * @return Whether the account can be liquidated\n */\n function liquidatableNext(address account, IProduct product) external view returns (bool) {\n return product.maintenanceNext(account).gt(collateral(account, product));\n }\n\n /**\n * @notice Injects additional collateral into a product to resolve shortfall\n * @dev Shortfall is a measure of settled insolvency in the market\n * This hook can be used by the product owner or an insurance fund to re-capitalize an insolvent market\n * @param product Product to resolve shortfall for\n * @param amount Amount of shortfall to resolve\n */\n function resolveShortfall(IProduct product, UFixed18 amount) external isProduct(product) notPaused {\n _products[product].resolve(amount);\n token.pull(msg.sender, amount);\n\n emit ShortfallResolution(product, amount);\n }\n\n /**\n * @notice Claims all of `msg.sender`'s fees\n */\n function claimFee() external notPaused {\n UFixed18 amount = fees[msg.sender];\n\n fees[msg.sender] = UFixed18Lib.ZERO;\n token.push(msg.sender, amount);\n\n emit FeeClaim(msg.sender, amount);\n }\n\n /// @dev Ensure that the address is non-zero\n modifier notZeroAddress(address account) {\n if (account == address(0)) revert CollateralZeroAddressError();\n\n _;\n }\n\n /// @dev Ensure that the user has sufficient margin for both current and next maintenance\n modifier maintenanceInvariant(address account, IProduct product) {\n _;\n\n UFixed18 maintenance = product.maintenance(account);\n UFixed18 maintenanceNext = product.maintenanceNext(account);\n\n if (UFixed18Lib.max(maintenance, maintenanceNext).gt(collateral(account, product)))\n revert CollateralInsufficientCollateralError();\n }\n\n /// @dev Ensure that the account is either empty or above the collateral minimum\n modifier collateralInvariant(address account, IProduct product) {\n _;\n\n UFixed18 accountCollateral = collateral(account, product);\n if (!accountCollateral.isZero() && accountCollateral.lt(controller().minCollateral()))\n revert CollateralUnderLimitError();\n }\n\n /// @dev Helper to fully settle an account's state\n modifier settleForAccount(address account, IProduct product) {\n product.settleAccount(account);\n\n _;\n }\n}\n" + }, + "contracts/collateral/types/OptimisticLedger.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\n\n/// @dev OptimisticLedger type\nstruct OptimisticLedger {\n /// @dev Individual account collateral balances\n mapping(address => UFixed18) balances;\n\n /// @dev Total ledger collateral balance\n UFixed18 total;\n\n /// @dev Total ledger collateral shortfall\n UFixed18 shortfall;\n}\nusing OptimisticLedgerLib for OptimisticLedger global;\n\n/**\n * @title OptimisticLedgerLib\n * @notice Library that manages a global vs account ledger where the global ledger is settled separately,\n * and ahead of, the user-level accounts.\n * @dev Ensures that no more collateral leaves the ledger than goes it, while allowing user-level accounts\n * to settle as a follow up step. Overdrafts on the user-level are accounted as \"shortall\". Shortfall\n * in the system is the quantity of insolvency that can be optionally resolved by the ledger owner.\n * Until the shortfall is resolved, collateral may be withdrawn from the ledger on a FCFS basis. However\n * once the ledger total has been depleted, users will not be able to withdraw even if they have non-zero\n * user level balances until the shortfall is resolved, recapitalizing the ledger.\n */\nlibrary OptimisticLedgerLib {\n /**\n * @notice Credits `account` with `amount` collateral\n * @param self The struct to operate on\n * @param account Account to credit collateral to\n * @param amount Amount of collateral to credit\n */\n function creditAccount(OptimisticLedger storage self, address account, UFixed18 amount) internal {\n self.balances[account] = self.balances[account].add(amount);\n self.total = self.total.add(amount);\n }\n\n /**\n * @notice Debits `account` `amount` collateral\n * @param self The struct to operate on\n * @param account Account to debit collateral from\n * @param amount Amount of collateral to debit\n */\n function debitAccount(OptimisticLedger storage self, address account, UFixed18 amount) internal {\n self.balances[account] = self.balances[account].sub(amount);\n self.total = self.total.sub(amount);\n }\n\n /**\n * @notice Credits `account` with `amount` collateral\n * @dev Funds come from inside the product, not totals are updated\n * Shortfall is created if more funds are debited from an account than exist\n * @param self The struct to operate on\n * @param account Account to credit collateral to\n * @param amount Amount of collateral to credit\n * @return newShortfall Any new shortfall incurred during this settlement\n */\n function settleAccount(OptimisticLedger storage self, address account, Fixed18 amount)\n internal returns (UFixed18 newShortfall) {\n Fixed18 newBalance = Fixed18Lib.from(self.balances[account]).add(amount);\n\n if (newBalance.sign() == -1) {\n newShortfall = newBalance.abs();\n newBalance = Fixed18Lib.ZERO;\n }\n\n self.balances[account] = newBalance.abs();\n self.shortfall = self.shortfall.add(newShortfall);\n }\n\n /**\n * @notice Debits ledger globally `amount` collateral\n * @dev Removes balance from total that is accounted for elsewhere (e.g. product-level accumulators)\n * @param self The struct to operate on\n * @param amount Amount of collateral to debit\n */\n function debit(OptimisticLedger storage self, UFixed18 amount) internal {\n self.total = self.total.sub(amount);\n }\n\n /**\n * @notice Reduces the amount of collateral shortfall in the ledger\n * @param self The struct to operate on\n * @param amount Amount of shortfall to resolve\n */\n function resolve(OptimisticLedger storage self, UFixed18 amount) internal {\n self.shortfall = self.shortfall.sub(amount);\n self.total = self.total.add(amount);\n }\n}\n" + }, + "contracts/controller/Controller.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol\";\nimport \"../interfaces/IController.sol\";\nimport \"../interfaces/ICollateral.sol\";\nimport \"../interfaces/IIncentivizer.sol\";\nimport \"../interfaces/IProduct.sol\";\n\n/**\n * @title Controller\n * @notice Manages creating new products and global protocol parameters.\n */\ncontract Controller is IController, UInitializable {\n /// @dev Collateral contract address for the protocol\n AddressStorage private constant _collateral = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.collateral\"));\n function collateral() public view returns (ICollateral) { return ICollateral(_collateral.read()); }\n\n /// @dev Incentivizer contract address for the protocol\n AddressStorage private constant _incentivizer = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.incentivizer\"));\n function incentivizer() public view returns (IIncentivizer) { return IIncentivizer(_incentivizer.read()); }\n\n /// @dev Product implementation beacon address for the protocol\n AddressStorage private constant _productBeacon = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.productBeacon\"));\n function productBeacon() public view returns (IBeacon) { return IBeacon(_productBeacon.read()); }\n\n /// @dev MultiInvoker contract address for the protocol\n AddressStorage private constant _multiInvoker = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.multiInvoker\"));\n function multiInvoker() public view returns (IMultiInvoker) { return IMultiInvoker(_multiInvoker.read()); }\n\n /// @dev Percent of collected fees that go to the protocol treasury vs the product treasury\n UFixed18Storage private constant _protocolFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.protocolFee\"));\n function protocolFee() public view returns (UFixed18) { return _protocolFee.read(); }\n\n /// @dev Minimum allowable funding fee for a product\n UFixed18Storage private constant _minFundingFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.minFundingFee\"));\n function minFundingFee() public view returns (UFixed18) { return _minFundingFee.read(); }\n\n /// @dev Fee on maintenance for liquidation\n UFixed18Storage private constant _liquidationFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.liquidationFee\"));\n function liquidationFee() public view returns (UFixed18) { return _liquidationFee.read(); }\n\n /// @dev Fee on incentivization programs\n UFixed18Storage private constant _incentivizationFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.incentivizationFee\"));\n function incentivizationFee() public view returns (UFixed18) { return _incentivizationFee.read(); }\n\n /// @dev Minimum allowable collateral amount per user account\n UFixed18Storage private constant _minCollateral = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.minCollateral\"));\n function minCollateral() public view returns (UFixed18) { return _minCollateral.read(); }\n\n /// @dev Maximum incentivization programs per product allowed\n Uint256Storage private constant _programsPerProduct = Uint256Storage.wrap(keccak256(\"equilibria.perennial.Controller.programsPerProduct\"));\n function programsPerProduct() public view returns (uint256) { return _programsPerProduct.read(); }\n\n /// @dev Protocol pauser address. address(0) defaults to owner(0)\n AddressStorage private constant _pauser = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.pauser\"));\n function pauser() public view returns (address) {\n address pauser_ = _pauser.read();\n return pauser_ == address(0) ? owner() : pauser_;\n }\n\n /// @dev The paused status of the protocol\n BoolStorage private constant _paused = BoolStorage.wrap(keccak256(\"equilibria.perennial.Controller.paused\"));\n function paused() public view returns (bool) { return _paused.read(); }\n\n /// @dev List of product coordinators\n Coordinator[] private _coordinators;\n\n /// @dev Mapping of the coordinator for each product\n mapping(IProduct => uint256) public coordinatorFor;\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n * @param collateral_ Collateral contract address\n * @param incentivizer_ Incentivizer contract address\n * @param productBeacon_ Product implementation beacon address\n */\n function initialize(\n ICollateral collateral_,\n IIncentivizer incentivizer_,\n IBeacon productBeacon_\n ) external initializer(1) {\n _createCoordinator();\n\n updateCollateral(collateral_);\n updateIncentivizer(incentivizer_);\n updateProductBeacon(productBeacon_);\n }\n\n /**\n * @notice Creates a new coordinator with `msg.sender` as the owner\n * @return New coordinator ID\n */\n function createCoordinator() external returns (uint256) {\n return _createCoordinator();\n }\n\n /**\n * @notice Creates a new coordinator with `msg.sender` as the owner\n * @dev `treasury` and `pauser` initialize as the 0-address, defaulting to the `owner`\n * @return New coordinator ID\n */\n function _createCoordinator() private returns (uint256) {\n uint256 coordinatorId = _coordinators.length;\n\n _coordinators.push(Coordinator({\n pendingOwner: address(0),\n owner: msg.sender,\n treasury: address(0)\n }));\n\n emit CoordinatorCreated(coordinatorId, msg.sender);\n\n return coordinatorId;\n }\n\n /**\n * @notice Updates the pending owner of an existing coordinator\n * @dev Must be called by the coordinator's current owner\n * @param coordinatorId Coordinator to update\n * @param newPendingOwner New pending owner address\n */\n function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external onlyOwner(coordinatorId) {\n _coordinators[coordinatorId].pendingOwner = newPendingOwner;\n emit CoordinatorPendingOwnerUpdated(coordinatorId, newPendingOwner);\n }\n\n /**\n * @notice Accepts ownership over an existing coordinator\n * @dev Must be called by the coordinator's pending owner\n * @param coordinatorId Coordinator to update\n */\n function acceptCoordinatorOwner(uint256 coordinatorId) external {\n Coordinator storage coordinator = _coordinators[coordinatorId];\n address newPendingOwner = coordinator.pendingOwner;\n\n if (msg.sender != newPendingOwner) revert ControllerNotPendingOwnerError(coordinatorId);\n\n coordinator.pendingOwner = address(0);\n coordinator.owner = newPendingOwner;\n emit CoordinatorOwnerUpdated(coordinatorId, newPendingOwner);\n }\n\n /**\n * @notice Updates the treasury of an existing coordinator\n * @dev Must be called by the coordinator's current owner. Defaults to the coordinator `owner` if set to address(0)\n * @param coordinatorId Coordinator to update\n * @param newTreasury New treasury address\n */\n function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external onlyOwner(coordinatorId) {\n _coordinators[coordinatorId].treasury = newTreasury;\n emit CoordinatorTreasuryUpdated(coordinatorId, newTreasury);\n }\n\n /**\n * @notice Creates a new product market with `provider`\n * @dev Can only be called by the coordinator owner\n * @param coordinatorId Coordinator that will own the product\n * @param productInfo Product params used to initialize the product\n * @return New product contract address\n */\n function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo)\n external onlyOwner(coordinatorId) returns (IProduct) {\n if (coordinatorId == 0) revert ControllerNoZeroCoordinatorError();\n\n BeaconProxy newProductProxy = new BeaconProxy(address(productBeacon()), abi.encodeCall(IProduct.initialize, productInfo));\n IProduct newProduct = IProduct(address(newProductProxy));\n coordinatorFor[newProduct] = coordinatorId;\n emit ProductCreated(newProduct, productInfo);\n\n return newProduct;\n }\n\n /**\n * @notice Updates the Collateral contract address\n * @param newCollateral New Collateral contract address\n */\n function updateCollateral(ICollateral newCollateral) public onlyOwner(0) {\n if (!Address.isContract(address(newCollateral))) revert ControllerNotContractAddressError();\n _collateral.store(address(newCollateral));\n emit CollateralUpdated(newCollateral);\n }\n\n /**\n * @notice Updates the Incentivizer contract address\n * @param newIncentivizer New Incentivizer contract address\n */\n function updateIncentivizer(IIncentivizer newIncentivizer) public onlyOwner(0) {\n if (!Address.isContract(address(newIncentivizer))) revert ControllerNotContractAddressError();\n _incentivizer.store(address(newIncentivizer));\n emit IncentivizerUpdated(newIncentivizer);\n }\n\n /**\n * @notice Updates the Product implementation beacon address\n * @param newProductBeacon New Product implementation beacon address\n */\n function updateProductBeacon(IBeacon newProductBeacon) public onlyOwner(0) {\n if (!Address.isContract(address(newProductBeacon))) revert ControllerNotContractAddressError();\n _productBeacon.store(address(newProductBeacon));\n emit ProductBeaconUpdated(newProductBeacon);\n }\n\n /**\n * @notice Updates the MultiInvoker contract address\n * @param newMultiInvoker New MultiInvoker contract address\n */\n function updateMultiInvoker(IMultiInvoker newMultiInvoker) public onlyOwner(0) {\n if (!Address.isContract(address(newMultiInvoker))) revert ControllerNotContractAddressError();\n _multiInvoker.store(address(newMultiInvoker));\n emit MultiInvokerUpdated(newMultiInvoker);\n }\n\n /**\n * @notice Updates the protocol-product fee split\n * @param newProtocolFee New protocol-product fee split\n */\n function updateProtocolFee(UFixed18 newProtocolFee) public onlyOwner(0) {\n if (newProtocolFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidProtocolFeeError();\n\n _protocolFee.store(newProtocolFee);\n emit ProtocolFeeUpdated(newProtocolFee);\n }\n\n /**\n * @notice Updates the minimum allowed funding fee\n * @param newMinFundingFee New minimum allowed funding fee\n */\n function updateMinFundingFee(UFixed18 newMinFundingFee) public onlyOwner(0) {\n if (newMinFundingFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidMinFundingFeeError();\n\n _minFundingFee.store(newMinFundingFee);\n emit MinFundingFeeUpdated(newMinFundingFee);\n }\n\n /**\n * @notice Updates the liquidation fee\n * @param newLiquidationFee New liquidation fee\n */\n function updateLiquidationFee(UFixed18 newLiquidationFee) public onlyOwner(0) {\n if (newLiquidationFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidLiquidationFeeError();\n\n _liquidationFee.store(newLiquidationFee);\n emit LiquidationFeeUpdated(newLiquidationFee);\n }\n\n /**\n * @notice Updates the incentivization fee\n * @param newIncentivizationFee New incentivization fee\n */\n function updateIncentivizationFee(UFixed18 newIncentivizationFee) public onlyOwner(0) {\n if (newIncentivizationFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidIncentivizationFeeError();\n\n _incentivizationFee.store(newIncentivizationFee);\n emit IncentivizationFeeUpdated(newIncentivizationFee);\n }\n\n /**\n * @notice Updates the minimum allowed collateral amount per user account\n * @param newMinCollateral New minimum allowed collateral amount\n */\n function updateMinCollateral(UFixed18 newMinCollateral) public onlyOwner(0) {\n _minCollateral.store(newMinCollateral);\n emit MinCollateralUpdated(newMinCollateral);\n }\n\n /**\n * @notice Updates the maximum incentivization programs per product allowed\n * @param newProgramsPerProduct New maximum incentivization programs per product allowed\n */\n function updateProgramsPerProduct(uint256 newProgramsPerProduct) public onlyOwner(0) {\n _programsPerProduct.store(newProgramsPerProduct);\n emit ProgramsPerProductUpdated(newProgramsPerProduct);\n }\n\n /**\n * @notice Updates the protocol pauser address. Zero address defaults to owner(0)\n * @param newPauser New protocol pauser address\n */\n function updatePauser(address newPauser) public onlyOwner(0) {\n _pauser.store(newPauser);\n emit PauserUpdated(newPauser);\n }\n\n /**\n * @notice Updates the protocol paused state\n * @param newPaused New protocol paused state\n */\n function updatePaused(bool newPaused) public onlyPauser {\n _paused.store(newPaused);\n emit PausedUpdated(newPaused);\n }\n\n /**\n * @notice Returns whether a contract is a product\n * @param product Contract address to check\n * @return Whether a contract is a product\n */\n function isProduct(IProduct product) external view returns (bool) {\n return coordinatorFor[product] != 0;\n }\n\n /**\n * @notice Returns coordinator state for coordinator `coordinatorId`\n * @param coordinatorId Coordinator to return for\n * @return Coordinator state\n */\n function coordinators(uint256 coordinatorId) external view returns (Coordinator memory) {\n return _coordinators[coordinatorId];\n }\n\n /**\n * @notice Returns the pending owner of the protocol\n * @return Owner of the protocol\n */\n function pendingOwner() public view returns (address) {\n return pendingOwner(0);\n }\n\n /**\n * @notice Returns the pending owner of the coordinator `coordinatorId`\n * @param coordinatorId Coordinator to return for\n * @return Pending owner of the coordinator\n */\n function pendingOwner(uint256 coordinatorId) public view returns (address) {\n return _coordinators[coordinatorId].pendingOwner;\n }\n\n /**\n * @notice Returns the owner of the protocol\n * @return Owner of the protocol\n */\n function owner() public view returns (address) {\n return owner(0);\n }\n\n /**\n * @notice Returns the owner of the coordinator `coordinatorId`\n * @param coordinatorId Coordinator to return for\n * @return Owner of the coordinator\n */\n function owner(uint256 coordinatorId) public view returns (address) {\n return _coordinators[coordinatorId].owner;\n }\n\n /**\n * @notice Returns the owner of the product `product`\n * @param product Product to return for\n * @return Owner of the product\n */\n function owner(IProduct product) external view returns (address) {\n return owner(coordinatorFor[product]);\n }\n\n /**\n * @notice Returns the treasury of the protocol\n * @dev Defaults to the `owner` when `treasury` is unset\n * @return Treasury of the protocol\n */\n function treasury() external view returns (address) {\n return treasury(0);\n }\n\n /**\n * @notice Returns the treasury of the coordinator `coordinatorId`\n * @dev Defaults to the `owner` when `treasury` is unset\n * @param coordinatorId Coordinator to return for\n * @return Treasury of the coordinator\n */\n function treasury(uint256 coordinatorId) public view returns (address) {\n address _treasury = _coordinators[coordinatorId].treasury;\n return _treasury == address(0) ? owner(coordinatorId) : _treasury;\n }\n\n /**\n * @notice Returns the treasury of the product `product`\n * @dev Defaults to the `owner` when `treasury` is unset\n * @param product Product to return for\n * @return Treasury of the product\n */\n function treasury(IProduct product) external view returns (address) {\n return treasury(coordinatorFor[product]);\n }\n\n /// @dev Only allow owner of `coordinatorId` to call\n modifier onlyOwner(uint256 coordinatorId) {\n if (msg.sender != owner(coordinatorId)) revert ControllerNotOwnerError(coordinatorId);\n\n _;\n }\n\n /// @dev Only allow the pauser to call\n modifier onlyPauser {\n if (msg.sender != pauser()) revert ControllerNotPauserError();\n\n _;\n }\n}\n" + }, + "contracts/controller/UControllerProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/root/storage/UStorage.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../interfaces/IController.sol\";\nimport \"../interfaces/IProduct.sol\";\n\n/**\n * @title UControllerProvider\n * @notice Mix-in that manages a controller pointer and associated permissioning modifiers.\n * @dev Uses unstructured storage so that it is safe to mix-in to upgreadable contracts without modifying\n * their storage layout.\n */\nabstract contract UControllerProvider is UInitializable {\n error NotOwnerError(uint256 coordinatorId);\n error NotProductError(IProduct product);\n error NotCollateralError();\n error PausedError();\n error InvalidControllerError();\n error NotAccountOrMultiInvokerError(address account, address operator);\n\n /// @dev The controller contract address\n AddressStorage private constant _controller = AddressStorage.wrap(keccak256(\"equilibria.perennial.UControllerProvider.controller\"));\n function controller() public view returns (IController) { return IController(_controller.read()); }\n\n /**\n * @notice Initializes the contract state\n * @param controller_ Protocol Controller contract address\n */\n // solhint-disable-next-line func-name-mixedcase\n function __UControllerProvider__initialize(IController controller_) internal onlyInitializer {\n if (!Address.isContract(address(controller_))) revert InvalidControllerError();\n _controller.store(address(controller_));\n }\n\n /// @dev Only allow a valid product contract to call\n modifier onlyProduct {\n if (!controller().isProduct(IProduct(msg.sender))) revert NotProductError(IProduct(msg.sender));\n\n _;\n }\n\n /// @dev Verify that `product` is a valid product contract\n modifier isProduct(IProduct product) {\n if (!controller().isProduct(product)) revert NotProductError(product);\n\n _;\n }\n\n /// @dev Only allow the Collateral contract to call\n modifier onlyCollateral {\n if (msg.sender != address(controller().collateral())) revert NotCollateralError();\n\n _;\n }\n\n /// @dev Only allow the coordinator owner to call\n modifier onlyOwner(uint256 coordinatorId) {\n if (msg.sender != controller().owner(coordinatorId)) revert NotOwnerError(coordinatorId);\n\n _;\n }\n\n /// @dev Only allow if the protocol is currently unpaused\n modifier notPaused() {\n if (controller().paused()) revert PausedError();\n\n _;\n }\n\n /// @dev Ensure the `msg.sender` is ether the `account` or the Controller's multiInvoker\n modifier onlyAccountOrMultiInvoker(address account) {\n if (!(msg.sender == account || msg.sender == address(controller().multiInvoker()))) {\n revert NotAccountOrMultiInvokerError(account, msg.sender);\n }\n _;\n }\n}\n" + }, + "contracts/forwarder/Forwarder.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"../interfaces/IForwarder.sol\";\n\n/**\n * @title Forwarder\n * @notice Facilitates collateral deposits to the protocol where the amount is supplied\n * in USDC then wrapped as DSU before being deposited.\n */\ncontract Forwarder is IForwarder {\n // @dev USDC stablecoin\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n // @dev DSU stablecoin\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n\n /// @dev Contract that wraps USDC to DSU\n IBatcher public immutable batcher;\n\n /// @dev Contract managing state for collateral accounts in the protocol\n ICollateral public immutable collateral;\n\n /**\n * @notice Initializes the contract state\n * @param usdc_ The USDC token contract address\n * @param dsu_ The DSU token contract address\n * @param batcher_ The USDC-to-DSU batcher contract address\n * @param collateral_ The perennial collateral contract address\n */\n constructor(\n Token6 usdc_,\n Token18 dsu_,\n IBatcher batcher_,\n ICollateral collateral_\n ) {\n if (!Address.isContract(Token6.unwrap(usdc_))) revert ForwarderNotContractAddressError();\n if (!Address.isContract(Token18.unwrap(dsu_))) revert ForwarderNotContractAddressError();\n if (!Address.isContract(address(batcher_))) revert ForwarderNotContractAddressError();\n if (!Address.isContract(address(collateral_))) revert ForwarderNotContractAddressError();\n\n USDC = usdc_;\n DSU = dsu_;\n batcher = batcher_;\n collateral = collateral_;\n\n USDC.approve(address(batcher));\n DSU.approve(address(collateral));\n }\n\n /**\n * @notice Pulls `amount` of USDC from `msg.sender`'s balance, wraps it as DSU,\n and deposits it as collateral to `account`'s `product` account\n * @param account Account to deposit the collateral for\n * @param product Product to credit the collateral to\n * @param amount 18 decimals-normalized stablecoin (USDC, DSU) value of collateral to deposit\n */\n function wrapAndDeposit(\n address account,\n IProduct product,\n UFixed18 amount\n ) external {\n USDC.pull(msg.sender, amount, true);\n batcher.wrap(amount, address(this));\n collateral.depositTo(account, product, amount);\n emit WrapAndDeposit(account, product, amount);\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/emptyset-batcher/batcher/Batcher.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/emptyset-batcher/batcher/Batcher.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Arbitrum.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Arbitrum.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Optimism.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Optimism.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/governance/TimelockController.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/governance/TimelockController.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol';\n" + }, + "contracts/incentivizer/Incentivizer.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/root/control/unstructured/UReentrancyGuard.sol\";\nimport \"../interfaces/IIncentivizer.sol\";\nimport \"../interfaces/IController.sol\";\nimport \"../controller/UControllerProvider.sol\";\nimport \"./types/ProductManager.sol\";\n\n/**\n * @title Incentivizer\n * @notice Manages logic and state for all incentive programs in the protocol.\n */\ncontract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, UReentrancyGuard {\n /// @dev Product management state\n mapping(IProduct => ProductManager) private _products;\n\n /// @dev Fees that have been collected, but remain unclaimed\n mapping(Token18 => UFixed18) public fees;\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n * @param controller_ Factory contract address\n */\n function initialize(IController controller_) external initializer(1) {\n __UControllerProvider__initialize(controller_);\n __UReentrancyGuard__initialize();\n }\n\n /**\n * @notice Creates a new incentive program\n * @dev Must be called as the product or protocol owner\n * @param product The product to create the new program on\n * @param programInfo Parameters for the new program\n * @return programId New program's ID\n */\n function create(IProduct product, ProgramInfo calldata programInfo)\n external\n nonReentrant\n isProduct(product)\n notPaused\n onlyOwner(programInfo.coordinatorId)\n returns (uint256 programId) {\n IController _controller = controller();\n\n // Validate\n if (programInfo.coordinatorId != 0 && programInfo.coordinatorId != _controller.coordinatorFor(product))\n revert IncentivizerNotAllowedError(product);\n if (active(product) >= _controller.programsPerProduct())\n revert IncentivizerTooManyProgramsError();\n ProgramInfoLib.validate(programInfo);\n\n // Take fee\n (ProgramInfo memory newProgramInfo, UFixed18 programFeeAmount) = ProgramInfoLib.deductFee(programInfo, _controller.incentivizationFee());\n fees[newProgramInfo.token] = fees[newProgramInfo.token].add(programFeeAmount);\n\n // Register program\n programId = _products[product].register(newProgramInfo);\n\n // Charge creator\n newProgramInfo.token.pull(msg.sender, programInfo.amount.sum());\n\n emit ProgramCreated(\n product,\n programId,\n newProgramInfo,\n programFeeAmount\n );\n }\n\n /**\n * @notice Completes an in-progress program early\n * @dev Must be called as the program owner\n * @param product Product that the program is running on\n * @param programId Program to complete early\n */\n function complete(IProduct product, uint256 programId)\n external\n nonReentrant\n isProgram(product, programId)\n notPaused\n onlyProgramOwner(product, programId)\n {\n ProductManagerLib.SyncResult memory syncResult = _products[product].complete(product, programId);\n _handleSyncResult(product, syncResult);\n }\n\n /**\n * @notice Starts and completes programs as they become available\n * @dev Called every settle() from each product\n * @param currentOracleVersion The preloaded current oracle version\n */\n function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external onlyProduct {\n IProduct product = IProduct(msg.sender);\n\n ProductManagerLib.SyncResult[] memory syncResults = _products[product].sync(product, currentOracleVersion);\n for (uint256 i = 0; i < syncResults.length; i++) {\n _handleSyncResult(product, syncResults[i]);\n }\n }\n\n /**\n * @notice Handles refunding and event emitting on program start and completion\n * @param product Product that the program is running on\n * @param syncResult The data from the sync event to handle\n */\n function _handleSyncResult(IProduct product, ProductManagerLib.SyncResult memory syncResult) private {\n uint256 programId = syncResult.programId;\n if (!syncResult.refundAmount.isZero())\n _products[product].token(programId).push(treasury(product, programId), syncResult.refundAmount);\n if (syncResult.versionStarted != 0)\n emit ProgramStarted(product, programId, syncResult.versionStarted);\n if (syncResult.versionComplete != 0)\n emit ProgramComplete(product, programId, syncResult.versionComplete);\n }\n\n /**\n * @notice Settles unsettled balance for `account`\n * @dev Called immediately proceeding a position update in the corresponding product\n * @param account Account to sync\n * @param currentOracleVersion The preloaded current oracle version\n */\n function syncAccount(\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) external onlyProduct {\n IProduct product = IProduct(msg.sender);\n _products[product].syncAccount(product, account, currentOracleVersion);\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for `product` programs\n * @param product Product to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function claim(IProduct product, uint256[] calldata programIds)\n external\n nonReentrant\n {\n _claimProduct(msg.sender, product, programIds);\n }\n\n /**\n * @notice Claims all of `account`'s rewards for `product` programs\n * @param account Account to claim rewards for\n * @param product Product to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function claimFor(address account, IProduct product, uint256[] calldata programIds)\n external\n nonReentrant\n onlyAccountOrMultiInvoker(account)\n {\n _claimProduct(account, product, programIds);\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for a specific program\n * @param products Products to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function claim(IProduct[] calldata products, uint256[][] calldata programIds)\n external\n nonReentrant\n {\n if (products.length != programIds.length) revert IncentivizerBatchClaimArgumentMismatchError();\n for (uint256 i; i < products.length; i++) {\n _claimProduct(msg.sender, products[i], programIds[i]);\n }\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for `product` programs\n * @dev Internal helper with validation checks\n * @param account Account to claim rewards for\n * @param product Product to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function _claimProduct(address account, IProduct product, uint256[] memory programIds)\n private\n isProduct(product)\n notPaused\n settleForAccount(account, product)\n {\n for (uint256 i; i < programIds.length; i++) {\n _claimProgram(account, product, programIds[i]);\n }\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for `programId` on `product`\n * @dev Internal helper with validation checks\n * @param account Account to claim rewards for\n * @param product Product to claim rewards for\n * @param programId Program to claim rewards for\n */\n function _claimProgram(address account, IProduct product, uint256 programId)\n private\n isProgram(product, programId)\n {\n ProductManager storage productManager = _products[product];\n UFixed18 claimAmount = productManager.claim(account, programId);\n productManager.token(programId).push(account, claimAmount);\n emit Claim(product, account, programId, claimAmount);\n }\n\n /**\n * @notice Claims all `tokens` fees to the protocol treasury\n * @param tokens Tokens to claim fees for\n */\n function claimFee(Token18[] calldata tokens) external notPaused {\n for(uint256 i; i < tokens.length; i++) {\n Token18 token = tokens[i];\n UFixed18 amount = fees[token];\n\n fees[token] = UFixed18Lib.ZERO;\n token.push(controller().treasury(), amount);\n\n emit FeeClaim(token, amount);\n }\n }\n\n /**\n * @notice Returns the quantity of active programs for a given product\n * @param product Product to check for\n * @return Number of active programs\n */\n function active(IProduct product) public view returns (uint256) {\n return _products[product].active();\n }\n\n /**\n * @notice Returns the quantity of programs for a given product\n * @param product Product to check for\n * @return Number of programs (inactive or active)\n */\n function count(IProduct product) external view returns (uint256) {\n return _products[product].programInfos.length;\n }\n\n /**\n * @notice Returns program info for program `programId`\n * @param product Product to return for\n * @param programId Program to return for\n * @return Program info\n */\n function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory) {\n return _products[product].programInfos[programId];\n }\n\n /**\n * @notice Returns `account`'s total unclaimed rewards for a specific program\n * @param product Product to return for\n * @param account Account to return for\n * @param programId Program to return for\n * @return `account`'s total unclaimed rewards for `programId`\n */\n function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18) {\n return _products[product].unclaimed(account, programId);\n }\n\n /**\n * @notice Returns available rewards for a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return Available rewards for `programId`\n */\n function available(IProduct product, uint256 programId) external view returns (UFixed18) {\n return _products[product].programs[programId].available;\n }\n\n /**\n * @notice Returns the version started for a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The version started for `programId`\n */\n function versionStarted(IProduct product, uint256 programId) external view returns (uint256) {\n return _products[product].programs[programId].versionStarted;\n }\n\n /**\n * @notice Returns the version completed for a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The version completed for `programId`\n */\n function versionComplete(IProduct product, uint256 programId) external view returns (uint256) {\n return _products[product].programs[programId].versionComplete;\n }\n\n /**\n * @notice Returns the owner of a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The owner of `programId`\n */\n function owner(IProduct product, uint256 programId) public view returns (address) {\n return controller().owner(_products[product].programInfos[programId].coordinatorId);\n }\n\n /**\n * @notice Returns the treasury of a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The treasury of `programId`\n */\n function treasury(IProduct product, uint256 programId) public view returns (address) {\n return controller().treasury(_products[product].programInfos[programId].coordinatorId);\n }\n\n /// @dev Helper to fully settle an account's state\n modifier settleForAccount(address account, IProduct product) {\n product.settleAccount(account);\n\n _;\n }\n\n /// @dev Only allow the owner of `programId` to call\n modifier onlyProgramOwner(IProduct product, uint256 programId) {\n if (msg.sender != owner(product, programId)) revert IncentivizerNotProgramOwnerError(product, programId);\n\n _;\n }\n\n /// @dev Only allow a valid `programId`\n modifier isProgram(IProduct product, uint256 programId) {\n if (!_products[product].valid(programId)) revert IncentivizerInvalidProgramError(product, programId);\n\n _;\n }\n}\n" + }, + "contracts/incentivizer/types/ProductManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport \"./Program.sol\";\n\n/// @dev ProductManager type\nstruct ProductManager {\n /// @dev Static program state\n ProgramInfo[] programInfos;\n\n /// @dev Dynamic program state\n mapping(uint256 => Program) programs;\n\n /// @dev Mapping of all active programs for each product\n EnumerableSet.UintSet activePrograms;\n\n /// @dev Mapping of all active programs for each user\n mapping(address => EnumerableSet.UintSet) activeProgramsFor;\n\n /// @dev Mapping of the next program to watch for for each user\n mapping(address => uint256) nextProgramFor;\n}\nusing ProductManagerLib for ProductManager global;\n\n/**\n * @title ProductManagerLib\n * @notice Library that manages each product's incentivization state and logic.\n */\nlibrary ProductManagerLib {\n using EnumerableSet for EnumerableSet.UintSet;\n\n /// @dev Result data for a sync event\n struct SyncResult {\n /// @dev The programId that was updated\n uint256 programId;\n\n /// @dev If non-zero, the new versionStart value of the program\n uint256 versionStarted;\n\n /// @dev If non-zero, the new versionComplete value of the program\n uint256 versionComplete;\n\n /// @dev If non-zero, the amount to refund due to completion\n UFixed18 refundAmount;\n }\n\n /**\n * @notice Registers a new program on this product\n * @param self The Product manager to operate on\n * @param programInfo The static program info\n * @return programId The new program's ID\n */\n function register(\n ProductManager storage self,\n ProgramInfo memory programInfo\n ) internal returns (uint256 programId) {\n programId = self.programInfos.length;\n self.programInfos.push(programInfo);\n self.programs[programId].initialize(programInfo);\n self.activePrograms.add(programId);\n }\n\n /**\n * @notice Syncs this product with the latest data\n * @param self The Program manager to operate on\n * @param product This Product\n * @param currentOracleVersion The preloaded current oracle version\n */\n function sync(\n ProductManager storage self,\n IProduct product,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal returns (SyncResult[] memory results) {\n\n uint256[] memory activeProgramIds = self.activePrograms.values();\n results = new SyncResult[](activeProgramIds.length);\n\n for (uint256 i; i < activeProgramIds.length; i++) {\n // Load program\n uint256 programId = activeProgramIds[i];\n ProgramInfo memory programInfo = self.programInfos[programId];\n Program storage program = self.programs[programId];\n\n // If timestamp-started, grab current version (first version after start)\n uint256 versionStarted;\n if (program.versionStarted == 0 && programInfo.isStarted(currentOracleVersion.timestamp)) {\n versionStarted = _start(self, programId, currentOracleVersion);\n }\n\n // If timestamp-completed, grab previous version (last version before completion)\n uint256 versionComplete;\n UFixed18 refundAmount;\n if (program.versionComplete == 0 && programInfo.isComplete(currentOracleVersion.timestamp)) {\n (versionComplete, refundAmount) = _complete(self, product, programId);\n }\n\n // Save result\n results[i] = SyncResult(programId, versionStarted, versionComplete, refundAmount);\n }\n }\n\n /**\n * @notice Syncs an account for this product with the latest data\n * @dev Assumes that sync() has already been called as part of the transaction flow\n * @param self The Program manager to operate on\n * @param product This Product\n * @param account The account to sync\n * @param currentOracleVersion The preloaded current oracle version\n */\n function syncAccount(\n ProductManager storage self,\n IProduct product,\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal {\n\n // Add any unseen programs\n uint256 fromProgramId = self.nextProgramFor[account];\n uint256 toProgramId = self.programInfos.length;\n for (uint256 programId = fromProgramId; programId < toProgramId; programId++) {\n self.activeProgramsFor[account].add(programId);\n }\n self.nextProgramFor[account] = toProgramId;\n\n // Settle programs\n uint256[] memory activeProgramIds = self.activeProgramsFor[account].values();\n for (uint256 i; i < activeProgramIds.length; i++) {\n uint256 programId = activeProgramIds[i];\n Program storage program = self.programs[programId];\n program.settle(product, self.programInfos[programId], account, currentOracleVersion);\n if (!self.activePrograms.contains(programId) && currentOracleVersion.version >= program.versionComplete) {\n self.activeProgramsFor[account].remove(programId);\n }\n }\n }\n\n /**\n * @notice Returns the quantity of active programs for this product\n * @param self The Program manager to operate on\n * @return The quantity of active programs\n */\n function active(ProductManager storage self) internal view returns (uint256) {\n return self.activePrograms.length();\n }\n\n /**\n * @notice Forces the specified program to complete if it hasn't already\n * @param self The Program manager to operate on\n * @param product The Product to operate on\n * @param programId The Program to complete\n * @return result The sync result data from completion\n */\n function complete(\n ProductManager storage self,\n IProduct product,\n uint256 programId\n ) internal returns (SyncResult memory result) {\n Program storage program = self.programs[programId];\n\n // If not started, start first\n if (program.versionStarted == 0) {\n result.versionStarted = _start(self, programId, product.currentVersion());\n }\n\n // If not completed already, complete\n if (program.versionComplete == 0) {\n (result.versionComplete, result.refundAmount) = _complete(self, product, programId);\n }\n }\n\n /**\n * @notice Starts the program\n * @dev Rewards do not start accruing until the program has started\n * Internal helper, does not prevent incorrectly-timed starting\n * @param self The Program manager to operate on\n * @param programId The Program to start\n * @param currentOracleVersion The effective starting oracle version\n * @return versionStarted The version that the program started\n */\n function _start(\n ProductManager storage self,\n uint256 programId,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal returns (uint256 versionStarted) {\n versionStarted = currentOracleVersion.version;\n self.programs[programId].start(currentOracleVersion.version);\n }\n\n /**\n * @notice Completes the program\n * @dev Completion stops rewards from accruing\n * Internal helper, does not prevent incorrectly-timed completion\n * @param self The Program manager to operate on\n * @param product The Product to operate on\n * @param programId The Program to complete\n * @return versionComplete The version that the program complete\n * @return refundAmount The refunded token amount\n */\n function _complete(\n ProductManager storage self,\n IProduct product,\n uint256 programId\n ) internal returns (uint256 versionComplete, UFixed18 refundAmount) {\n (versionComplete, refundAmount) = self.programs[programId].complete(product, self.programInfos[programId]);\n self.activePrograms.remove(programId);\n }\n\n /**\n * @notice Claims all of `account`'s rewards for a specific program\n * @param self The Program manager to operate on\n * @param account Account to claim rewards for\n * @param programId Program to claim rewards for\n * @return Amount claimed\n */\n function claim(ProductManager storage self, address account, uint256 programId) internal returns (UFixed18) {\n return self.programs[programId].claim(account);\n }\n\n /**\n * @notice Returns the total amount of unclaimed rewards for account `account`\n * @param self The Program manager to operate on\n * @param account The account to check for\n * @param programId The Program to check for\n * @return Total amount of unclaimed rewards for account\n */\n function unclaimed(ProductManager storage self, address account, uint256 programId) internal view returns (UFixed18) {\n if (!valid(self, programId)) return (UFixed18Lib.ZERO);\n return self.programs[programId].settled[account];\n }\n\n /**\n * @notice Returns the token denominatino of the program's rewards\n * @param self The Program manager to operate on\n * @param programId The Program to check for\n * @return The token for the program\n */\n function token(ProductManager storage self, uint256 programId) internal view returns (Token18) {\n return self.programInfos[programId].token;\n }\n\n /**\n * @notice Returns whether the supplied programId is valid\n * @param self The Program manager to operate on\n * @param programId The Program to check for\n * @return Whether the supplied programId is valid\n */\n function valid(ProductManager storage self, uint256 programId) internal view returns (bool) {\n return programId < self.programInfos.length;\n }\n}\n" + }, + "contracts/incentivizer/types/Program.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../interfaces/types/ProgramInfo.sol\";\n\n/// @dev Program type\nstruct Program {\n /// @dev Mapping of latest rewards settled for each account\n mapping(address => UFixed18) settled;\n\n /// @dev Total amount of rewards yet to be claimed\n UFixed18 available;\n\n /// @dev Oracle version that the program started, 0 when hasn't started\n uint256 versionStarted;\n\n /// @dev Oracle version that the program completed, 0 is still ongoing\n uint256 versionComplete;\n}\nusing ProgramLib for Program global;\n\n/**\n * @title ProgramLib\n * @notice Library that manages all of the mutable state for a single incentivization program.\n */\nlibrary ProgramLib {\n /**\n * @notice Initializes the program state\n * @param self The Program to operate on\n * @param programInfo Static program information\n */\n function initialize(Program storage self, ProgramInfo memory programInfo) internal {\n self.available = programInfo.amount.sum();\n }\n\n /**\n * @notice Starts the program\n * @dev Rewards do not start accruing until the program has started accruing\n * Does not stop double-starting\n * @param self The Program to operate on\n * @param oracleVersion The effective starting oracle version\n */\n function start(Program storage self, uint256 oracleVersion) internal {\n self.versionStarted = oracleVersion;\n }\n\n /**\n * @notice Completes the program\n * @dev Completion stops rewards from accruing\n * Does not prevent double-completion\n * @param self The Program to operate on\n * @param product The Product to operate on\n * @param programInfo Static program information\n * @return versionComplete The version that the program completed on\n * @return refundAmount The refund amount from the program\n */\n function complete(\n Program storage self,\n IProduct product,\n ProgramInfo memory programInfo\n ) internal returns (uint256 versionComplete, UFixed18 refundAmount) {\n uint256 versionStarted = self.versionStarted;\n versionComplete = Math.max(versionStarted, product.latestVersion());\n self.versionComplete = versionComplete;\n\n IOracleProvider.OracleVersion memory fromOracleVersion = product.atVersion(versionStarted);\n IOracleProvider.OracleVersion memory toOracleVersion = product.atVersion(versionComplete);\n\n uint256 inactiveDuration = programInfo.duration - (toOracleVersion.timestamp - fromOracleVersion.timestamp);\n refundAmount = programInfo.amount.sum().muldiv(inactiveDuration, programInfo.duration);\n self.available = self.available.sub(refundAmount);\n }\n\n /**\n * @notice Settles unclaimed rewards for account `account`\n * @param self The Program to operate on\n * @param product The Product to operate on\n * @param programInfo Static program information\n * @param account The account to settle for\n * @param currentOracleVersion The preloaded current oracle version\n */\n function settle(\n Program storage self,\n IProduct product,\n ProgramInfo memory programInfo,\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal {\n UFixed18 unsettledAmount = _unsettled(self, product, programInfo, account, currentOracleVersion);\n self.settled[account] = self.settled[account].add(unsettledAmount);\n self.available = self.available.sub(unsettledAmount);\n }\n\n /**\n * @notice Claims settled rewards for account `account`\n * @param self The Program to operate on\n * @param account The account to claim for\n */\n function claim(Program storage self, address account) internal returns (UFixed18 claimedAmount) {\n claimedAmount = self.settled[account];\n self.settled[account] = UFixed18Lib.ZERO;\n }\n\n /**\n * @notice Returns the unsettled amount of unclaimed rewards for account `account`\n * @dev Clears when a program is closed\n * Assumes that position is unchanged since last settlement, must be settled prior to user position update\n * @param self The Program to operate on\n * @param product The Product to operate on\n * @param programInfo Static program information\n * @param account The account to claim for\n * @param currentOracleVersion Current oracle version\n * @return amount Amount of unsettled rewards for account\n */\n function _unsettled(\n Program storage self,\n IProduct product,\n ProgramInfo memory programInfo,\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) private view returns (UFixed18 amount) {\n // program stage overview\n //\n // V = latest user settle version, V' = current user settle version\n // S = versionStarted, E = versionEnded\n //\n // (1) V V' S E program not yet started\n // (2) V S V' E use versionStarted -> V' for userShareDelta\n // (3) S V V' E use V -> V' for userShareDelta\n // (4) S V E V' use V -> versionComplete for userShareDelta\n // (5) S E V V' program already completed\n // (6) V S E V' use versionStarted -> versionComplete for userShareDelta\n //\n // NOTE: V == S and V' == E both default to the inner case\n\n (uint256 _versionStarted, uint256 _versionComplete) = (\n self.versionStarted == 0 ? currentOracleVersion.version : self.versionStarted, // start must be no earlier than current version\n self.versionComplete == 0 ? type(uint256).max : self.versionComplete // we don't know when completion occurs\n );\n\n // accruing must start between self.versionStarted and self.versionComplete\n uint256 fromVersion = Math.min(_versionComplete, Math.max(_versionStarted, product.latestVersion(account)));\n // accruing must complete between self.versionStarted and self.versionComplete, we know self.versionStarted must be no earlier than current version\n uint256 toVersion = Math.min(_versionComplete, currentOracleVersion.version);\n\n Accumulator memory globalShareDelta = product.shareAtVersion(toVersion).sub(product.shareAtVersion(fromVersion));\n Accumulator memory computedUserShareDelta = product.position(account).mul(globalShareDelta);\n amount = UFixed18Lib.from(programInfo.amountPerShare().mul(computedUserShareDelta).sum());\n }\n}\n" + }, + "contracts/interfaces/ICollateral.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/number/types/Fixed18.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"./IController.sol\";\nimport \"./IProduct.sol\";\n\ninterface ICollateral {\n event Deposit(address indexed user, IProduct indexed product, UFixed18 amount);\n event Withdrawal(address indexed user, IProduct indexed product, UFixed18 amount);\n event AccountSettle(IProduct indexed product, address indexed account, Fixed18 amount, UFixed18 newShortfall);\n event ProductSettle(IProduct indexed product, UFixed18 protocolFee, UFixed18 productFee);\n event Liquidation(address indexed user, IProduct indexed product, address liquidator, UFixed18 fee);\n event ShortfallResolution(IProduct indexed product, UFixed18 amount);\n event FeeClaim(address indexed account, UFixed18 amount);\n\n error CollateralCantLiquidate(UFixed18 totalMaintenance, UFixed18 totalCollateral);\n error CollateralInsufficientCollateralError();\n error CollateralUnderLimitError();\n error CollateralZeroAddressError();\n error CollateralAccountLiquidatingError(address account);\n\n function token() external view returns (Token18);\n function fees(address account) external view returns (UFixed18);\n function initialize(IController controller_) external;\n function depositTo(address account, IProduct product, UFixed18 amount) external;\n function withdrawTo(address receiver, IProduct product, UFixed18 amount) external;\n function withdrawFrom(address account, address receiver, IProduct product, UFixed18 amount) external;\n function liquidate(address account, IProduct product) external;\n function settleAccount(address account, Fixed18 amount) external;\n function settleProduct(UFixed18 amount) external;\n function collateral(address account, IProduct product) external view returns (UFixed18);\n function collateral(IProduct product) external view returns (UFixed18);\n function shortfall(IProduct product) external view returns (UFixed18);\n function liquidatable(address account, IProduct product) external view returns (bool);\n function liquidatableNext(address account, IProduct product) external view returns (bool);\n function resolveShortfall(IProduct product, UFixed18 amount) external;\n function claimFee() external;\n}\n" + }, + "contracts/interfaces/IContractPayoffProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\n\ninterface IContractPayoffProvider {\n function payoff(Fixed18 price) external view returns (Fixed18 payoff);\n}\n" + }, + "contracts/interfaces/IController.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\";\nimport \"./ICollateral.sol\";\nimport \"./IIncentivizer.sol\";\nimport \"./IProduct.sol\";\nimport \"./IMultiInvoker.sol\";\nimport \"./types/PayoffDefinition.sol\";\n\ninterface IController {\n /// @dev Coordinator of a one or many products\n struct Coordinator {\n /// @dev Pending owner of the product, can accept ownership\n address pendingOwner;\n\n /// @dev Owner of the product, allowed to update select parameters\n address owner;\n\n /// @dev Treasury of the product, collects fees\n address treasury;\n }\n\n event CollateralUpdated(ICollateral newCollateral);\n event IncentivizerUpdated(IIncentivizer newIncentivizer);\n event ProductBeaconUpdated(IBeacon newProductBeacon);\n event MultiInvokerUpdated(IMultiInvoker newMultiInvoker);\n event ProtocolFeeUpdated(UFixed18 newProtocolFee);\n event MinFundingFeeUpdated(UFixed18 newMinFundingFee);\n event LiquidationFeeUpdated(UFixed18 newLiquidationFee);\n event IncentivizationFeeUpdated(UFixed18 newIncentivizationFee);\n event MinCollateralUpdated(UFixed18 newMinCollateral);\n event ProgramsPerProductUpdated(uint256 newProgramsPerProduct);\n event PauserUpdated(address newPauser);\n event PausedUpdated(bool newPaused);\n event CoordinatorPendingOwnerUpdated(uint256 indexed coordinatorId, address newPendingOwner);\n event CoordinatorOwnerUpdated(uint256 indexed coordinatorId, address newOwner);\n event CoordinatorTreasuryUpdated(uint256 indexed coordinatorId, address newTreasury);\n event CoordinatorCreated(uint256 indexed coordinatorId, address owner);\n event ProductCreated(IProduct indexed product, IProduct.ProductInfo productInfo);\n\n error ControllerNoZeroCoordinatorError();\n error ControllerNotPauserError();\n error ControllerNotOwnerError(uint256 controllerId);\n error ControllerNotPendingOwnerError(uint256 controllerId);\n error ControllerInvalidProtocolFeeError();\n error ControllerInvalidMinFundingFeeError();\n error ControllerInvalidLiquidationFeeError();\n error ControllerInvalidIncentivizationFeeError();\n error ControllerNotContractAddressError();\n\n function collateral() external view returns (ICollateral);\n function incentivizer() external view returns (IIncentivizer);\n function productBeacon() external view returns (IBeacon);\n function multiInvoker() external view returns (IMultiInvoker);\n function coordinators(uint256 collateralId) external view returns (Coordinator memory);\n function coordinatorFor(IProduct product) external view returns (uint256);\n function protocolFee() external view returns (UFixed18);\n function minFundingFee() external view returns (UFixed18);\n function liquidationFee() external view returns (UFixed18);\n function incentivizationFee() external view returns (UFixed18);\n function minCollateral() external view returns (UFixed18);\n function programsPerProduct() external view returns (uint256);\n function pauser() external view returns (address);\n function paused() external view returns (bool);\n function initialize(ICollateral collateral_, IIncentivizer incentivizer_, IBeacon productBeacon_) external;\n function createCoordinator() external returns (uint256);\n function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external;\n function acceptCoordinatorOwner(uint256 coordinatorId) external;\n function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external;\n function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo) external returns (IProduct);\n function updateCollateral(ICollateral newCollateral) external;\n function updateIncentivizer(IIncentivizer newIncentivizer) external;\n function updateProductBeacon(IBeacon newProductBeacon) external;\n function updateMultiInvoker(IMultiInvoker newMultiInvoker) external;\n function updateProtocolFee(UFixed18 newProtocolFee) external;\n function updateMinFundingFee(UFixed18 newMinFundingFee) external;\n function updateLiquidationFee(UFixed18 newLiquidationFee) external;\n function updateIncentivizationFee(UFixed18 newIncentivizationFee) external;\n function updateMinCollateral(UFixed18 newMinCollateral) external;\n function updateProgramsPerProduct(uint256 newProductsPerProduct) external;\n function updatePauser(address newPauser) external;\n function updatePaused(bool newPaused) external;\n function isProduct(IProduct product) external view returns (bool);\n function owner() external view returns (address);\n function owner(uint256 coordinatorId) external view returns (address);\n function owner(IProduct product) external view returns (address);\n function treasury() external view returns (address);\n function treasury(uint256 coordinatorId) external view returns (address);\n function treasury(IProduct product) external view returns (address);\n}\n" + }, + "contracts/interfaces/IForwarder.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"./ICollateral.sol\";\n\ninterface IForwarder {\n error ForwarderNotContractAddressError();\n\n event WrapAndDeposit(address indexed account, IProduct indexed product, UFixed18 amount);\n\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\n function batcher() external view returns (IBatcher);\n function collateral() external view returns (ICollateral);\n function wrapAndDeposit(address account, IProduct product, UFixed18 amount) external;\n}\n" + }, + "contracts/interfaces/IIncentivizer.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./types/ProgramInfo.sol\";\nimport \"./IController.sol\";\nimport \"./IProduct.sol\";\n\ninterface IIncentivizer {\n event ProgramCreated(IProduct indexed product, uint256 indexed programId, ProgramInfo programInfo, UFixed18 programFeeAmount);\n event ProgramStarted(IProduct indexed product, uint256 indexed programId, uint256 version);\n event ProgramComplete(IProduct indexed product, uint256 indexed programId, uint256 version);\n event Claim(IProduct indexed product, address indexed account, uint256 indexed programId, UFixed18 amount);\n event FeeClaim(Token18 indexed token, UFixed18 amount);\n\n error IncentivizerNotAllowedError(IProduct product);\n error IncentivizerTooManyProgramsError();\n error IncentivizerNotProgramOwnerError(IProduct product, uint256 programId);\n error IncentivizerInvalidProgramError(IProduct product, uint256 programId);\n error IncentivizerBatchClaimArgumentMismatchError();\n\n function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory);\n function fees(Token18 token) external view returns (UFixed18);\n function initialize(IController controller_) external;\n function create(IProduct product, ProgramInfo calldata info) external returns (uint256);\n function complete(IProduct product, uint256 programId) external;\n function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external;\n function syncAccount(address account, IOracleProvider.OracleVersion memory currentOracleVersion) external;\n function claim(IProduct product, uint256[] calldata programIds) external;\n function claimFor(address account, IProduct product, uint256[] calldata programIds) external;\n function claim(IProduct[] calldata products, uint256[][] calldata programIds) external;\n function claimFee(Token18[] calldata tokens) external;\n function active(IProduct product) external view returns (uint256);\n function count(IProduct product) external view returns (uint256);\n function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18);\n function available(IProduct product, uint256 programId) external view returns (UFixed18);\n function versionStarted(IProduct product, uint256 programId) external view returns (uint256);\n function versionComplete(IProduct product, uint256 programId) external view returns (uint256);\n function owner(IProduct product, uint256 programId) external view returns (address);\n function treasury(IProduct product, uint256 programId) external view returns (address);\n}\n" + }, + "contracts/interfaces/IMultiInvoker.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\";\n\nimport \"./IController.sol\";\nimport \"./ICollateral.sol\";\nimport \"./IProduct.sol\";\n\ninterface IPerennialVault {\n event Deposit(address indexed sender, address indexed account, uint256 version, UFixed18 assets);\n event Redemption(address indexed sender, address indexed account, uint256 version, UFixed18 shares);\n event Claim(address indexed sender, address indexed account, UFixed18 assets);\n\n function deposit(UFixed18 assets, address account) external;\n function redeem(UFixed18 shares, address account) external;\n function claim(address account) external;\n}\n\ninterface IMultiInvoker {\n /// @dev Core protocol actions that can be composed\n enum PerennialAction {\n NO_OP,\n DEPOSIT,\n WITHDRAW,\n OPEN_TAKE,\n CLOSE_TAKE,\n OPEN_MAKE,\n CLOSE_MAKE,\n CLAIM,\n WRAP,\n UNWRAP,\n WRAP_AND_DEPOSIT,\n WITHDRAW_AND_UNWRAP,\n VAULT_DEPOSIT,\n VAULT_REDEEM,\n VAULT_CLAIM,\n VAULT_WRAP_AND_DEPOSIT\n }\n\n /// @dev Struct for action invocation\n struct Invocation {\n PerennialAction action;\n bytes args;\n }\n\n function initialize() external;\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\n function batcher() external view returns (IBatcher);\n function controller() external view returns (IController);\n function collateral() external view returns (ICollateral);\n function reserve() external view returns (IEmptySetReserve);\n function invoke(Invocation[] calldata invocations) external;\n}\n" + }, + "contracts/interfaces/IMultiInvokerRollup.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./IMultiInvoker.sol\";\n\ninterface IMultiInvokerRollup is IMultiInvoker {\n event AddressAddedToCache(address indexed addr, uint256 nonce);\n /// @dev reverts when calldata has an issue. causes: length of bytes in a uint > || cache index empty\n error MultiInvokerRollupInvalidCalldataError();\n\n function addressCache(uint256 nonce) external view returns(address);\n function addressLookup(address addr) external view returns(uint256 nonce);\n}\n" + }, + "contracts/interfaces/IParamProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\";\nimport \"./types/PendingFeeUpdates.sol\";\n\ninterface IParamProvider {\n event MaintenanceUpdated(UFixed18 newMaintenance, uint256 version);\n event FundingFeeUpdated(UFixed18 newFundingFee, uint256 version);\n event MakerFeeUpdated(UFixed18 newMakerFee, uint256 version);\n event PendingMakerFeeUpdated(UFixed18 newMakerFee);\n event TakerFeeUpdated(UFixed18 newTakerFee, uint256 version);\n event PendingTakerFeeUpdated(UFixed18 newTakerFee);\n event PositionFeeUpdated(UFixed18 newPositionFee, uint256 version);\n event PendingPositionFeeUpdated(UFixed18 newPositionFee);\n event MakerLimitUpdated(UFixed18 newMakerLimit, uint256 version);\n event JumpRateUtilizationCurveUpdated(\n JumpRateUtilizationCurve,\n uint256 version\n );\n\n error ParamProviderInvalidParamValue();\n\n function maintenance() external view returns (UFixed18);\n function updateMaintenance(UFixed18 newMaintenance) external;\n function fundingFee() external view returns (UFixed18);\n function updateFundingFee(UFixed18 newFundingFee) external;\n function makerFee() external view returns (UFixed18);\n function updateMakerFee(UFixed18 newMakerFee) external;\n function takerFee() external view returns (UFixed18);\n function updateTakerFee(UFixed18 newTakerFee) external;\n function positionFee() external view returns (UFixed18);\n function updatePositionFee(UFixed18 newPositionFee) external;\n function makerLimit() external view returns (UFixed18);\n function updateMakerLimit(UFixed18 newMakerLimit) external;\n function utilizationCurve() external view returns (JumpRateUtilizationCurve memory);\n function updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) external;\n function pendingFeeUpdates() external view returns (PendingFeeUpdates memory);\n}\n" + }, + "contracts/interfaces/IPayoffProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./types/PayoffDefinition.sol\";\n\ninterface IPayoffProvider {\n event OracleUpdated(address newOracle, uint256 oracleVersion);\n\n error PayoffProviderInvalidOracle();\n error PayoffProviderInvalidPayoffDefinitionError();\n\n function oracle() external view returns (IOracleProvider);\n function payoffDefinition() external view returns (PayoffDefinition memory);\n function currentVersion() external view returns (IOracleProvider.OracleVersion memory);\n function atVersion(uint256 oracleVersion) external view returns (IOracleProvider.OracleVersion memory);\n}\n" + }, + "contracts/interfaces/IPerennialLens.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./IProduct.sol\";\nimport \"./ICollateral.sol\";\nimport \"./IController.sol\";\n\n/**\n * @title Lens contract to conveniently pull protocol, product, and userproduct data\n * @notice All functions should be called using `callStatic`\n */\ninterface IPerennialLens {\n /// @dev Snapshot of Protocol information\n struct ProtocolSnapshot {\n ICollateral collateral;\n IIncentivizer incentivizer;\n Token18 collateralToken;\n UFixed18 protocolFee;\n UFixed18 liquidationFee;\n UFixed18 minCollateral;\n bool paused;\n }\n\n /// @dev Snapshot of Product information\n struct ProductSnapshot {\n IProduct.ProductInfo productInfo;\n address productAddress;\n Fixed18 rate;\n Fixed18 dailyRate;\n IOracleProvider.OracleVersion latestVersion;\n UFixed18 maintenance;\n UFixed18 collateral;\n UFixed18 shortfall;\n PrePosition pre;\n Position position;\n UFixed18 productFee;\n UFixed18 protocolFee;\n Position openInterest;\n }\n\n /// @dev Snapshot of User state for a Product\n struct UserProductSnapshot {\n address productAddress;\n address userAddress;\n UFixed18 collateral;\n UFixed18 maintenance;\n PrePosition pre;\n Position position;\n bool liquidatable;\n bool liquidating;\n Position openInterest;\n UFixed18 fees;\n UFixed18 exposure;\n }\n\n // Protocol Values\n function controller() external view returns (IController);\n function collateral() external view returns (ICollateral);\n\n // Snapshot Functions for batch values\n function snapshot() external returns (ProtocolSnapshot memory);\n function snapshots(IProduct[] calldata productAddresses) external returns (ProductSnapshot[] memory);\n function snapshot(IProduct product) external returns (ProductSnapshot memory);\n function snapshots(address account, IProduct[] calldata productAddresses) external returns (UserProductSnapshot[] memory);\n function snapshot(address account, IProduct product) external returns (UserProductSnapshot memory);\n\n // Product Values\n function name(IProduct product) external view returns (string memory);\n function symbol(IProduct product) external view returns (string memory);\n function info(IProduct product) external view returns (IProduct.ProductInfo memory _info);\n function collateral(IProduct product) external returns (UFixed18);\n function shortfall(IProduct product) external returns (UFixed18);\n function pre(IProduct product) external returns (PrePosition memory);\n function fees(IProduct product) external returns (UFixed18 protocolFees, UFixed18 productFees);\n function position(IProduct product) external returns (Position memory);\n function globalPosition(IProduct product) external returns (PrePosition memory, Position memory);\n function latestVersion(IProduct product) external returns (IOracleProvider.OracleVersion memory);\n function atVersions(IProduct product, uint[] memory versions) external returns (IOracleProvider.OracleVersion[] memory prices);\n function rate(IProduct product) external returns (Fixed18);\n function openInterest(IProduct product) external returns (Position memory);\n function dailyRate(IProduct product) external returns (Fixed18);\n\n // UserProduct Values\n function collateral(address account, IProduct product) external returns (UFixed18);\n function maintenance(address account, IProduct product) external returns (UFixed18);\n function liquidatable(address account, IProduct product) external returns (bool);\n function liquidating(address account, IProduct product) external returns (bool);\n function pre(address account, IProduct product) external returns (PrePosition memory);\n function position(address account, IProduct product) external returns (Position memory);\n function userPosition(address account, IProduct product) external returns (PrePosition memory, Position memory);\n function fees(address account, IProduct product) external returns (UFixed18);\n function openInterest(address account, IProduct product) external returns (Position memory);\n function exposure(address account, IProduct product) external returns (UFixed18);\n function maintenanceRequired(\n address account,\n IProduct product,\n UFixed18 positionSize\n ) external returns (UFixed18);\n function unclaimedIncentiveRewards(address account, IProduct product)\n external\n returns (Token18[] memory tokens, UFixed18[] memory amounts);\n function unclaimedIncentiveRewards(\n address account,\n IProduct product,\n uint256[] calldata programIds\n ) external returns (Token18[] memory tokens, UFixed18[] memory amounts);\n}\n" + }, + "contracts/interfaces/IProduct.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\";\nimport \"./IPayoffProvider.sol\";\nimport \"./IParamProvider.sol\";\nimport \"./types/PayoffDefinition.sol\";\nimport \"./types/Position.sol\";\nimport \"./types/PrePosition.sol\";\nimport \"./types/Accumulator.sol\";\n\ninterface IProduct is IPayoffProvider, IParamProvider {\n /// @dev Product Creation parameters\n struct ProductInfo {\n /// @dev name of the product\n string name;\n\n /// @dev symbol of the product\n string symbol;\n\n /// @dev product payoff definition\n PayoffDefinition payoffDefinition;\n\n /// @dev oracle address\n IOracleProvider oracle;\n\n /// @dev product maintenance ratio\n UFixed18 maintenance;\n\n /// @dev product funding fee\n UFixed18 fundingFee;\n\n /// @dev product maker fee\n UFixed18 makerFee;\n\n /// @dev product taker fee\n UFixed18 takerFee;\n\n /// @dev product position fee share\n UFixed18 positionFee;\n\n /// @dev product maker limit\n UFixed18 makerLimit;\n\n /// @dev utulization curve definition\n JumpRateUtilizationCurve utilizationCurve;\n }\n\n event Settle(uint256 preVersion, uint256 toVersion);\n event AccountSettle(address indexed account, uint256 preVersion, uint256 toVersion);\n event MakeOpened(address indexed account, uint256 version, UFixed18 amount);\n event TakeOpened(address indexed account, uint256 version, UFixed18 amount);\n event MakeClosed(address indexed account, uint256 version, UFixed18 amount);\n event TakeClosed(address indexed account, uint256 version, UFixed18 amount);\n event ClosedUpdated(bool indexed newClosed, uint256 version);\n\n error ProductInsufficientLiquidityError(UFixed18 socializationFactor);\n error ProductDoubleSidedError();\n error ProductOverClosedError();\n error ProductInsufficientCollateralError();\n error ProductInLiquidationError();\n error ProductMakerOverLimitError();\n error ProductOracleBootstrappingError();\n error ProductClosedError();\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function initialize(ProductInfo calldata productInfo_) external;\n function settle() external;\n function settleAccount(address account) external;\n function openTake(UFixed18 amount) external;\n function openTakeFor(address account, UFixed18 amount) external;\n function closeTake(UFixed18 amount) external;\n function closeTakeFor(address account, UFixed18 amount) external;\n function openMake(UFixed18 amount) external;\n function openMakeFor(address account, UFixed18 amount) external;\n function closeMake(UFixed18 amount) external;\n function closeMakeFor(address account, UFixed18 amount) external;\n function closeAll(address account) external;\n function maintenance(address account) external view returns (UFixed18);\n function maintenanceNext(address account) external view returns (UFixed18);\n function isClosed(address account) external view returns (bool);\n function isLiquidating(address account) external view returns (bool);\n function position(address account) external view returns (Position memory);\n function pre(address account) external view returns (PrePosition memory);\n function latestVersion() external view returns (uint256);\n function positionAtVersion(uint256 oracleVersion) external view returns (Position memory);\n function pre() external view returns (PrePosition memory);\n function valueAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\n function shareAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\n function latestVersion(address account) external view returns (uint256);\n function rate(Position memory position) external view returns (Fixed18);\n function closed() external view returns (bool);\n function updateClosed(bool newClosed) external;\n function updateOracle(IOracleProvider newOracle) external;\n}\n" + }, + "contracts/interfaces/types/Accumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\nimport \"./PackedAccumulator.sol\";\n\n/// @dev Accumulator type\nstruct Accumulator {\n /// @dev maker accumulator per share\n Fixed18 maker;\n /// @dev taker accumulator per share\n Fixed18 taker;\n}\nusing AccumulatorLib for Accumulator global;\n\n/**\n * @title AccountAccumulatorLib\n * @notice Library that surfaces math operations for the Accumulator type.\n * @dev Accumulators track the cumulative change in position value over time for the maker and taker positions\n * respectively. Account-level accumulators can then use two of these values `a` and `a'` to compute the\n * change in position value since last sync. This change in value is then used to compute P&L and fees.\n */\nlibrary AccumulatorLib {\n /**\n * @notice Creates a packed accumulator from an accumulator\n * @param self an accumulator\n * @return New packed accumulator\n */\n function pack(Accumulator memory self) internal pure returns (PackedAccumulator memory) {\n return PackedAccumulator({maker: self.maker.pack(), taker: self.taker.pack()});\n }\n\n /**\n * @notice Adds two accumulators together\n * @param a The first accumulator to sum\n * @param b The second accumulator to sum\n * @return The resulting summed accumulator\n */\n function add(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\n return Accumulator({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\n }\n\n /**\n * @notice Subtracts accumulator `b` from `a`\n * @param a The accumulator to subtract from\n * @param b The accumulator to subtract\n * @return The resulting subtracted accumulator\n */\n function sub(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\n return Accumulator({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\n }\n\n /**\n * @notice Multiplies two accumulators together\n * @param a The first accumulator to multiply\n * @param b The second accumulator to multiply\n * @return The resulting multiplied accumulator\n */\n function mul(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\n return Accumulator({maker: a.maker.mul(b.maker), taker: a.taker.mul(b.taker)});\n }\n\n /**\n * @notice Sums the maker and taker together from a single accumulator\n * @param self The struct to operate on\n * @return The sum of its maker and taker\n */\n function sum(Accumulator memory self) internal pure returns (Fixed18) {\n return self.maker.add(self.taker);\n }\n}\n" + }, + "contracts/interfaces/types/PackedAccumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/PackedFixed18.sol\";\nimport \"./Accumulator.sol\";\n\n/// @dev PackedAccumulator type\nstruct PackedAccumulator {\n /// @dev maker accumulator per share\n PackedFixed18 maker;\n /// @dev taker accumulator per share\n PackedFixed18 taker;\n}\nusing PackedAccumulatorLib for PackedAccumulator global;\n\n/**\n * @title PackedAccumulatorLib\n * @dev A packed version of the Accumulator which takes up a single storage slot using `PackedFixed18` values.\n * @notice Library for the packed Accumulator type.\n */\nlibrary PackedAccumulatorLib {\n /**\n * @notice Creates an accumulator from a packed accumulator\n * @param self packed accumulator\n * @return New accumulator\n */\n function unpack(PackedAccumulator memory self) internal pure returns (Accumulator memory) {\n return Accumulator({maker: self.maker.unpack(), taker: self.taker.unpack()});\n }\n}\n" + }, + "contracts/interfaces/types/PackedPosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/PackedUFixed18.sol\";\nimport \"./Position.sol\";\n\n/// @dev PackedPosition type\nstruct PackedPosition {\n /// @dev Quantity of the maker position\n PackedUFixed18 maker;\n /// @dev Quantity of the taker position\n PackedUFixed18 taker;\n}\nusing PackedPositionLib for PackedPosition global;\n\n/**\n * @title PackedPositionLib\n * @dev A packed version of the Position which takes up a single storage slot using `PackedFixed18` values.\n * @notice Library for the packed Position type.\n */\nlibrary PackedPositionLib {\n /**\n * @notice Creates an position from a packed position\n * @param self packed position\n * @return New position\n */\n function unpack(PackedPosition memory self) internal pure returns (Position memory) {\n return Position({maker: self.maker.unpack(), taker: self.taker.unpack()});\n }\n}\n" + }, + "contracts/interfaces/types/PayoffDefinition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../../interfaces/IContractPayoffProvider.sol\";\n\n/// @dev PayoffDefinition tyoe\nstruct PayoffDefinition {\n PayoffDefinitionLib.PayoffType payoffType;\n PayoffDefinitionLib.PayoffDirection payoffDirection;\n bytes30 data;\n}\nusing PayoffDefinitionLib for PayoffDefinition global;\ntype PayoffDefinitionStorage is bytes32;\nusing PayoffDefinitionStorageLib for PayoffDefinitionStorage global;\n\n/**\n * @title PayoffDefinitionLib\n * @dev Library that surfaces logic for PayoffDefinition type functionality\n * @notice Library for the PayoffDefinition type. Performs validity and price transformation\n based on the payoff definition type.\n */\nlibrary PayoffDefinitionLib {\n using Address for address;\n\n error PayoffDefinitionUnsupportedTransform(PayoffType payoffType, PayoffDirection payoffDirection);\n error PayoffDefinitionNotContract(PayoffType payoffType, bytes30 data);\n\n /// @dev Payoff function type enum\n enum PayoffType { PASSTHROUGH, CONTRACT }\n enum PayoffDirection { LONG, SHORT }\n\n /**\n * @notice Checks validity of the payoff definition\n * @param self a payoff definition\n * @return Whether the payoff definition is valid for it's given type\n */\n function valid(PayoffDefinition memory self) internal view returns (bool) {\n if (self.payoffType == PayoffType.CONTRACT) return address(_providerContract(self)).isContract();\n\n // All other payoff types should have no data\n return uint(bytes32(self.data)) == 0;\n }\n\n /**\n * @notice Transforms a price based on the payoff definition\n * @param self a payoff definition\n * @param price raw oracle price\n * @return Price transformed by the payoff definition function\n */\n function transform(\n PayoffDefinition memory self,\n Fixed18 price\n ) internal view returns (Fixed18) {\n PayoffType payoffType = self.payoffType;\n PayoffDirection payoffDirection = self.payoffDirection;\n Fixed18 transformedPrice;\n\n // First get the price depending on the type\n if (payoffType == PayoffType.PASSTHROUGH) transformedPrice = price;\n else if (payoffType == PayoffType.CONTRACT) transformedPrice = _payoffFromContract(self, price);\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\n\n // Then transform it depending on the direction flag\n if (self.payoffDirection == PayoffDirection.LONG) return transformedPrice;\n else if (self.payoffDirection == PayoffDirection.SHORT) return transformedPrice.mul(Fixed18Lib.NEG_ONE);\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\n }\n\n /**\n * @notice Parses the data field into an address\n * @dev Reverts if payoffType is not CONTRACT\n * @param self a payoff definition\n * @return IContractPayoffProvider address\n */\n function _providerContract(\n PayoffDefinition memory self\n ) private pure returns (IContractPayoffProvider) {\n if (self.payoffType != PayoffType.CONTRACT) revert PayoffDefinitionNotContract(self.payoffType, self.data);\n // Shift to pull the last 20 bytes, then cast to an address\n return IContractPayoffProvider(address(bytes20(self.data << 80)));\n }\n\n /**\n * @notice Performs a price transformation by calling the underlying payoff contract\n * @param self a payoff definition\n * @param price raw oracle price\n * @return Price transformed by the payoff definition function on the contract\n */\n function _payoffFromContract(\n PayoffDefinition memory self,\n Fixed18 price\n ) private view returns (Fixed18) {\n bytes memory ret = address(_providerContract(self)).functionStaticCall(\n abi.encodeCall(IContractPayoffProvider.payoff, price)\n );\n return Fixed18.wrap(abi.decode(ret, (int256)));\n }\n}\n\n/**\n * @title PayoffDefinitionStorageLib\n * @notice Library that surfaces storage read and writes for the PayoffDefinition type\n */\nlibrary PayoffDefinitionStorageLib {\n function read(PayoffDefinitionStorage self) internal view returns (PayoffDefinition memory) {\n return _storagePointer(self);\n }\n\n function store(PayoffDefinitionStorage self, PayoffDefinition memory value) internal {\n PayoffDefinition storage storagePointer = _storagePointer(self);\n\n storagePointer.payoffType = value.payoffType;\n storagePointer.payoffDirection = value.payoffDirection;\n storagePointer.data = value.data;\n }\n\n function _storagePointer(\n PayoffDefinitionStorage self\n ) private pure returns (PayoffDefinition storage pointer) {\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\n }\n}\n" + }, + "contracts/interfaces/types/PendingFeeUpdates.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\n\n/// @dev PendingFeeUpdates type. Fees can be between 0 and 1 ** 10^18, so uint64 is sufficient\nstruct PendingFeeUpdates {\n bool makerFeeUpdated;\n uint64 pendingMakerFee;\n bool takerFeeUpdated;\n uint64 pendingTakerFee;\n bool positionFeeUpdated;\n uint64 pendingPositionFee;\n}\nusing PendingFeeUpdatesLib for PendingFeeUpdates global;\ntype PendingFeeUpdatesStorage is bytes32;\nusing PendingFeeUpdatesStorageLib for PendingFeeUpdatesStorage global;\n\n/**\n * @title PendingFeeUpdatesLib\n * @dev Library that surfaces convenience functions for the PendingFeeUpdates type\n * @notice Library for the PendingFeeUpdates type. Allows for setting and reading fee updates and clearing state\n */\nlibrary PendingFeeUpdatesLib {\n error PendingFeeUpdatesUnsupportedValue(UFixed18 value);\n\n /**\n * @notice Updates the pending maker fee to `newMakerFee` and sets the `makerFeeUpdated` flag\n * @dev Reverts if `newMakerFee` is invalid\n * @param self PendingFeeUpdates struct\n * @param newMakerFee new maker fee value\n */\n function updateMakerFee(PendingFeeUpdates memory self, UFixed18 newMakerFee) internal pure {\n if (UFixed18.unwrap(newMakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newMakerFee);\n self.pendingMakerFee = uint64(UFixed18.unwrap(newMakerFee));\n self.makerFeeUpdated = true;\n }\n\n /// @dev Returns the UFixed18-wrapped pending maker fee\n function makerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(self.pendingMakerFee));\n }\n\n /**\n * @notice Updates the pending taker fee to `newTakerFee` and sets the `takerFeeUpdated` flag\n * @dev Reverts if `newTakerFee` is invalid\n * @param self PendingFeeUpdates struct\n * @param newTakerFee new taker fee value\n */\n function updateTakerFee(PendingFeeUpdates memory self, UFixed18 newTakerFee) internal pure {\n if (UFixed18.unwrap(newTakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newTakerFee);\n self.pendingTakerFee = uint64(UFixed18.unwrap(newTakerFee));\n self.takerFeeUpdated = true;\n }\n\n /// @dev Returns the UFixed18-wrapped pending taker fee\n function takerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(self.pendingTakerFee));\n }\n\n /**\n * @notice Updates the pending position fee to `newPositionFee` and sets the `positionFeeUpdated` flag\n * @dev Reverts if `newPositionFee` is invalid\n * @param self PendingFeeUpdates struct\n * @param newPositionFee new position fee value\n */\n function updatePositionFee(PendingFeeUpdates memory self, UFixed18 newPositionFee) internal pure {\n if (UFixed18.unwrap(newPositionFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newPositionFee);\n self.pendingPositionFee = uint64(UFixed18.unwrap(newPositionFee));\n self.positionFeeUpdated = true;\n }\n\n /// @dev Returns the UFixed18-wrapped pending position fee\n function positionFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(self.pendingPositionFee));\n }\n\n /// @dev Returns true if any of the updated flags are true\n function hasUpdates(PendingFeeUpdates memory self) internal pure returns (bool) {\n return self.makerFeeUpdated || self.takerFeeUpdated || self.positionFeeUpdated;\n }\n\n /// @dev Resets all struct values to defaults\n function clear(PendingFeeUpdates memory self) internal pure {\n self.makerFeeUpdated = false;\n self.pendingMakerFee = 0;\n self.takerFeeUpdated = false;\n self.pendingTakerFee = 0;\n self.positionFeeUpdated = false;\n self.pendingPositionFee = 0;\n }\n}\n\n/**\n * @title PendingFeeUpdatesStorageLib\n * @notice Library that surfaces storage read and writes for the PendingFeeUpdates type\n */\nlibrary PendingFeeUpdatesStorageLib {\n struct PendingFeeUpdatesStoragePointer {\n PendingFeeUpdates value;\n }\n\n function read(PendingFeeUpdatesStorage self) internal view returns (PendingFeeUpdates memory) {\n return _storagePointer(self).value;\n }\n\n function store(PendingFeeUpdatesStorage self, PendingFeeUpdates memory value) internal {\n _storagePointer(self).value = value;\n }\n\n function _storagePointer(\n PendingFeeUpdatesStorage self\n ) private pure returns (PendingFeeUpdatesStoragePointer storage pointer) {\n /// @solidity memory-safe-assembly\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\n }\n}\n" + }, + "contracts/interfaces/types/Position.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"../IProduct.sol\";\nimport \"./Accumulator.sol\";\nimport \"./PrePosition.sol\";\nimport \"./PackedPosition.sol\";\n\n/// @dev Position type\nstruct Position {\n /// @dev Quantity of the maker position\n UFixed18 maker;\n /// @dev Quantity of the taker position\n UFixed18 taker;\n}\nusing PositionLib for Position global;\n\n/**\n * @title PositionLib\n * @notice Library that surfaces math and settlement computations for the Position type.\n * @dev Positions track the current quantity of the account's maker and taker positions respectively\n * denominated as a unit of the product's payoff function.\n */\nlibrary PositionLib {\n /**\n * @notice Creates a packed position from an position\n * @param self A position\n * @return New packed position\n */\n function pack(Position memory self) internal pure returns (PackedPosition memory) {\n return PackedPosition({maker: self.maker.pack(), taker: self.taker.pack()});\n }\n\n /**\n * @notice Returns whether the position is fully empty\n * @param self A position\n * @return Whether the position is empty\n */\n function isEmpty(Position memory self) internal pure returns (bool) {\n return self.maker.isZero() && self.taker.isZero();\n }\n\n /**\n * @notice Adds position `a` and `b` together, returning the result\n * @param a The first position to sum\n * @param b The second position to sum\n * @return Resulting summed position\n */\n function add(Position memory a, Position memory b) internal pure returns (Position memory) {\n return Position({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\n }\n\n /**\n * @notice Subtracts position `b` from `a`, returning the result\n * @param a The position to subtract from\n * @param b The position to subtract\n * @return Resulting subtracted position\n */\n function sub(Position memory a, Position memory b) internal pure returns (Position memory) {\n return Position({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\n }\n\n /**\n * @notice Multiplies position `self` by accumulator `accumulator` and returns the resulting accumulator\n * @param self The Position to operate on\n * @param accumulator The accumulator to multiply by\n * @return Resulting multiplied accumulator\n */\n function mul(Position memory self, Accumulator memory accumulator) internal pure returns (Accumulator memory) {\n return Accumulator({\n maker: Fixed18Lib.from(self.maker).mul(accumulator.maker),\n taker: Fixed18Lib.from(self.taker).mul(accumulator.taker)\n });\n }\n\n /**\n * @notice Scales position `self` by fixed-decimal `scale` and returns the resulting position\n * @param self The Position to operate on\n * @param scale The Fixed-decimal to scale by\n * @return Resulting scaled position\n */\n function mul(Position memory self, UFixed18 scale) internal pure returns (Position memory) {\n return Position({maker: self.maker.mul(scale), taker: self.taker.mul(scale)});\n }\n\n /**\n * @notice Divides position `self` by `b` and returns the resulting accumulator\n * @param self The Position to operate on\n * @param b The number to divide by\n * @return Resulting divided accumulator\n */\n function div(Position memory self, uint256 b) internal pure returns (Accumulator memory) {\n return Accumulator({\n maker: Fixed18Lib.from(self.maker).div(Fixed18Lib.from(UFixed18Lib.from(b))),\n taker: Fixed18Lib.from(self.taker).div(Fixed18Lib.from(UFixed18Lib.from(b)))\n });\n }\n\n /**\n * @notice Returns the maximum of `self`'s maker and taker values\n * @param self The struct to operate on\n * @return Resulting maximum value\n */\n function max(Position memory self) internal pure returns (UFixed18) {\n return UFixed18Lib.max(self.maker, self.taker);\n }\n\n /**\n * @notice Sums the maker and taker together from a single position\n * @param self The struct to operate on\n * @return The sum of its maker and taker\n */\n function sum(Position memory self) internal pure returns (UFixed18) {\n return self.maker.add(self.taker);\n }\n\n /**\n * @notice Computes the next position after the pending-settlement position delta is included\n * @param self The current Position\n * @param pre The pending-settlement position delta\n * @return Next Position\n */\n function next(Position memory self, PrePosition memory pre) internal pure returns (Position memory) {\n return sub(add(self, pre.openPosition), pre.closePosition);\n }\n\n /**\n * @notice Returns the settled position at oracle version `toOracleVersion`\n * @dev Checks if a new position is ready to be settled based on the provided `toOracleVersion`\n * and `pre` and returns accordingly\n * @param self The current Position\n * @param pre The pending-settlement position delta\n * @param toOracleVersion The oracle version to settle to\n * @return Settled position at oracle version\n * @return Whether a new position was settled\n */\n function settled(\n Position memory self,\n PrePosition memory pre,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal pure returns (Position memory, bool) {\n return pre.canSettle(toOracleVersion) ? (next(self, pre), true) : (self, false);\n }\n\n /**\n * @notice Returns the socialization factor for the current position\n * @dev Socialization account for the case where `taker` > `maker` temporarily due to a liquidation\n * on the maker side. This dampens the taker's exposure pro-rata to ensure that the maker side\n * is never exposed over 1 x short.\n * @param self The Position to operate on\n * @return Socialization factor\n */\n function socializationFactor(Position memory self) internal pure returns (UFixed18) {\n return self.taker.isZero() ? UFixed18Lib.ONE : UFixed18Lib.min(UFixed18Lib.ONE, self.maker.div(self.taker));\n }\n}\n" + }, + "contracts/interfaces/types/PrePosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./Position.sol\";\nimport \"../IProduct.sol\";\n\n/// @dev PrePosition type\nstruct PrePosition {\n /// @dev Oracle version at which the new position delta was recorded\n uint256 oracleVersion;\n\n /// @dev Size of position to open at oracle version\n Position openPosition;\n\n /// @dev Size of position to close at oracle version\n Position closePosition;\n}\nusing PrePositionLib for PrePosition global;\n\n/**\n * @title PrePositionLib\n * @notice Library that manages a pre-settlement position delta.\n * @dev PrePositions track the currently awaiting-settlement deltas to a settled Position. These are\n * Primarily necessary to introduce lag into the settlement system such that oracle lag cannot be\n * gamed to a user's advantage. When a user opens or closes a new position, it sits as a PrePosition\n * for one oracle version until it's settle into the Position, making it then effective. PrePositions\n * are automatically settled at the correct oracle version even if a flywheel call doesn't happen until\n * several version into the future by using the historical version lookups in the corresponding \"Versioned\"\n * global state types.\n */\nlibrary PrePositionLib {\n /**\n * @notice Returns whether there is no pending-settlement position delta\n * @param self The struct to operate on\n * @return Whether the pending-settlement position delta is empty\n */\n function isEmpty(PrePosition memory self) internal pure returns (bool) {\n return self.openPosition.isEmpty() && self.closePosition.isEmpty();\n }\n\n /**\n * @notice Increments the maker side of the open position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The position amount to open\n */\n function openMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.openPosition.maker = self.openPosition.maker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Increments the maker side of the close position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The maker position amount to close\n */\n function closeMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.closePosition.maker = self.closePosition.maker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Increments the taker side of the open position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The taker position amount to open\n */\n function openTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.openPosition.taker = self.openPosition.taker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Increments the taker side of the close position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The taker position amount to close\n */\n function closeTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.closePosition.taker = self.closePosition.taker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Returns whether the the pending position delta can be settled at version `toOracleVersion`\n * @dev Pending-settlement positions deltas can be settled (1) oracle version after they are recorded\n * @param self The struct to operate on\n * @param toOracleVersion The potential oracle version to settle\n * @return Whether the position delta can be settled\n */\n function canSettle(\n PrePosition memory self,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal pure returns (bool) {\n return self.oracleVersion != 0 && toOracleVersion.version > self.oracleVersion;\n }\n\n /**\n * @notice Computes the fee incurred for opening or closing the pending-settlement position\n * @dev Must be called from a valid product to get the proper fee amounts\n * @param self The struct to operate on\n * @param latestOracleVersion The oracle version at which position was modified\n * @return The maker / taker fee incurred\n */\n function computeFee(\n PrePosition memory self,\n IOracleProvider.OracleVersion memory latestOracleVersion\n ) internal view returns (Position memory) {\n Position memory positionDelta = self.openPosition.add(self.closePosition);\n\n (UFixed18 makerNotional, UFixed18 takerNotional) = (\n Fixed18Lib.from(positionDelta.maker).mul(latestOracleVersion.price).abs(),\n Fixed18Lib.from(positionDelta.taker).mul(latestOracleVersion.price).abs()\n );\n\n IProduct product = IProduct(address(this));\n return Position(makerNotional.mul(product.makerFee()), takerNotional.mul(product.takerFee()));\n }\n\n /**\n * @notice Computes the next oracle version to settle\n * @dev - If there is no pending-settlement position delta, returns the current oracle version\n * - Otherwise returns the oracle version at which the pending-settlement position delta can be first settled\n *\n * Corresponds to point (b) in the Position settlement flow\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @return Next oracle version to settle\n */\n function settleVersion(PrePosition storage self, uint256 currentVersion) internal view returns (uint256) {\n uint256 _oracleVersion = self.oracleVersion;\n return _oracleVersion == 0 ? currentVersion : _oracleVersion + 1;\n }\n}\n" + }, + "contracts/interfaces/types/ProgramInfo.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"../IProduct.sol\";\nimport \"./Position.sol\";\nimport \"./Accumulator.sol\";\n\n/// @dev ProgramInfo type\nstruct ProgramInfo {\n /// @dev Coordinator for this program\n uint256 coordinatorId;\n\n /// @dev Amount of total maker and taker rewards\n Position amount;\n\n /// @dev start timestamp of the program\n uint256 start;\n\n /// @dev duration of the program (in seconds)\n uint256 duration;\n\n /**\n * @dev Reward ERC20 token contract\n * @notice Perennial does not support non-standard ERC20s as reward tokens for incentive programs, including,\n but not limited to: fee on transfer and rebase tokens. Using such a non-standard token will likely\n result in loss of funds.\n */\n Token18 token;\n}\nusing ProgramInfoLib for ProgramInfo global;\n\n/**\n * @title ProgramInfoLib\n * @notice Library that snapshots the static information for a single program.\n * @dev This information does not change during the operation of a program.\n */\nlibrary ProgramInfoLib {\n uint256 private constant MIN_DURATION = 1 days;\n uint256 private constant MAX_DURATION = 2 * 365 days;\n\n error ProgramInvalidStartError();\n error ProgramInvalidDurationError();\n\n /**\n * @notice Validates and creates a new Program\n * @dev Reverts for invalid programInfos\n * @param programInfo Un-sanitized static program information\n */\n function validate(ProgramInfo memory programInfo) internal view {\n if (isStarted(programInfo, block.timestamp)) revert ProgramInvalidStartError();\n if (programInfo.duration < MIN_DURATION || programInfo.duration > MAX_DURATION) revert ProgramInvalidDurationError();\n }\n\n /**\n * @notice Computes a new program info with the fee taken out of the amount\n * @param programInfo Original program info\n * @param incentivizationFee The incentivization fee\n * @return New program info\n * @return Fee amount\n */\n function deductFee(ProgramInfo memory programInfo, UFixed18 incentivizationFee)\n internal pure returns (ProgramInfo memory, UFixed18) {\n Position memory newProgramAmount = programInfo.amount.mul(UFixed18Lib.ONE.sub(incentivizationFee));\n UFixed18 programFeeAmount = programInfo.amount.sub(newProgramAmount).sum();\n programInfo.amount = newProgramAmount;\n return (programInfo, programFeeAmount);\n }\n\n /**\n * @notice Returns the maker and taker amounts per position share\n * @param self The ProgramInfo to operate on\n * @return programFee Amounts per share\n */\n function amountPerShare(ProgramInfo memory self) internal pure returns (Accumulator memory) {\n return self.amount.div(self.duration);\n }\n\n /**\n * @notice Returns whether the program has started by timestamp `timestamp`\n * @param self The ProgramInfo to operate on\n * @param timestamp Timestamp to check for\n * @return Whether the program has started\n */\n function isStarted(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\n return timestamp >= self.start;\n }\n\n /**\n * @notice Returns whether the program is completed by timestamp `timestamp`\n * @param self The ProgramInfo to operate on\n * @param timestamp Timestamp to check for\n * @return Whether the program is completed\n */\n function isComplete(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\n return timestamp >= (self.start + self.duration);\n }\n}\n" + }, + "contracts/multiinvoker/MultiInvoker.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\n\nimport \"../interfaces/IMultiInvoker.sol\";\n\ncontract MultiInvoker is IMultiInvoker, UInitializable {\n /// @dev USDC stablecoin address\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n /// @dev DSU address\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n\n /// @dev Batcher address\n IBatcher public immutable batcher;\n\n /// @dev Controller address\n IController public immutable controller;\n\n /// @dev Collateral address\n ICollateral public immutable collateral;\n\n /// @dev Reserve address\n IEmptySetReserve public immutable reserve;\n\n /**\n * @notice Initializes the immutable contract state\n * @dev Called at implementation instantiate and constant for that implementation.\n * @param usdc_ USDC stablecoin address\n * @param batcher_ Protocol Batcher address\n * @param reserve_ EmptySet Reserve address\n * @param controller_ Protocol Controller address\n */\n constructor(Token6 usdc_, IBatcher batcher_, IEmptySetReserve reserve_, IController controller_) {\n USDC = usdc_;\n batcher = batcher_;\n controller = controller_;\n collateral = controller.collateral();\n DSU = collateral.token();\n reserve = reserve_;\n }\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n */\n function initialize() external initializer(2) {\n if (address(batcher) != address(0)) {\n DSU.approve(address(batcher), UFixed18Lib.ZERO);\n DSU.approve(address(batcher));\n USDC.approve(address(batcher), UFixed18Lib.ZERO);\n USDC.approve(address(batcher));\n }\n\n DSU.approve(address(collateral), UFixed18Lib.ZERO);\n DSU.approve(address(collateral));\n\n DSU.approve(address(reserve), UFixed18Lib.ZERO);\n DSU.approve(address(reserve));\n USDC.approve(address(reserve), UFixed18Lib.ZERO);\n USDC.approve(address(reserve));\n }\n\n /**\n * @notice Executes a list of invocations in order\n * @param invocations The list of invocations to execute in order\n */\n function invoke(Invocation[] calldata invocations) external {\n\n for (uint256 i = 0; i < invocations.length; i++) {\n Invocation memory invocation = invocations[i];\n\n // Deposit from `msg.sender` into `account`s `product` collateral account\n if (invocation.action == PerennialAction.DEPOSIT) {\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n _deposit(account, product, amount);\n\n // Withdraw from `msg.sender`s `product` collateral account to `receiver`\n } else if (invocation.action == PerennialAction.WITHDRAW) {\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n _withdraw(receiver, product, amount);\n\n // Open a take position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.OPEN_TAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n _openTake(product, amount);\n\n // Close a take position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.CLOSE_TAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n _closeTake(product, amount);\n\n // Open a make position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.OPEN_MAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n _openMake(product, amount);\n\n // Close a make position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.CLOSE_MAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n _closeMake(product, amount);\n\n // Claim `msg.sender`s incentive reward for `product` programs\n } else if (invocation.action == PerennialAction.CLAIM) {\n (IProduct product, uint256[] memory programIds) = abi.decode(invocation.args, (IProduct, uint256[]));\n _claim(product, programIds);\n\n // Wrap `msg.sender`s USDC into DSU and return the DSU to `account`\n } else if (invocation.action == PerennialAction.WRAP) {\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\n _wrap(receiver, amount);\n\n // Unwrap `msg.sender`s DSU into USDC and return the USDC to `account`\n } else if (invocation.action == PerennialAction.UNWRAP) {\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\n _unwrap(receiver, amount);\n\n // Wrap `msg.sender`s USDC into DSU and deposit into `account`s `product` collateral account\n } else if (invocation.action == PerennialAction.WRAP_AND_DEPOSIT) {\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n _wrapAndDeposit(account, product, amount);\n }\n\n // Withdraw DSU from `msg.sender`s `product` collateral account, unwrap into USDC, and return the USDC to `receiver`\n else if (invocation.action == PerennialAction.WITHDRAW_AND_UNWRAP) {\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n _withdrawAndUnwrap(receiver, product, amount);\n }\n\n // Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account`\n else if (invocation.action == PerennialAction.VAULT_DEPOSIT) {\n (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18));\n _vaultDeposit(account, vault, amount);\n }\n\n // Redeem `shares` from from `vault` on behalf of `msg.sender`\n else if (invocation.action == PerennialAction.VAULT_REDEEM) {\n (IPerennialVault vault, UFixed18 shares) = abi.decode(invocation.args, (IPerennialVault, UFixed18));\n _vaultRedeem(vault, shares);\n }\n\n // Claim assets from `vault` on behalf of `owner`\n else if (invocation.action == PerennialAction.VAULT_CLAIM) {\n (address owner, IPerennialVault vault) = abi.decode(invocation.args, (address, IPerennialVault));\n _vaultClaim(vault, owner);\n }\n\n // Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault`\n else if (invocation.action == PerennialAction.VAULT_WRAP_AND_DEPOSIT) {\n (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18));\n _vaultWrapAndDeposit(account, vault, amount);\n }\n }\n }\n\n /**\n * @notice opens `amount` of take on behalf of `msg.sender` in `product`\n * @param product Product to increase take position of\n * @param amount Amount to increase take position by\n */\n function _openTake(IProduct product, UFixed18 amount) internal {\n product.openTakeFor(msg.sender, amount);\n }\n\n /**\n * @notice closes `amount` of take on behalf of `msg.sender` in `product`\n * @param product Product to decrease take position of\n * @param amount Amount to decrease take position by\n */\n function _closeTake(IProduct product, UFixed18 amount) internal {\n product.closeTakeFor(msg.sender, amount);\n }\n\n /**\n * @notice opens `amount` of make on behalf of `msg.sender` in `product`\n * @param product Product to increase make position of\n * @param amount Amount to increase make position by\n */\n function _openMake(IProduct product, UFixed18 amount) internal {\n product.openMakeFor(msg.sender, amount);\n }\n\n /**\n * @notice closes `amount` of make on behalf of `msg.sender` in `product`\n * @param product Product to decrease make position of\n * @param amount Amount to decrease make position by\n */\n function _closeMake(IProduct product, UFixed18 amount) internal {\n product.closeMakeFor(msg.sender, amount);\n }\n\n /**\n * @notice Deposits `amount` DSU from `msg.sender` into `account`s `product` collateral account\n * @param account Account to deposit funds on behalf of\n * @param product Product to deposit funds for\n * @param amount Amount of DSU to deposit into the collateral account\n */\n function _deposit(address account, IProduct product, UFixed18 amount) internal {\n // Pull the token from the `msg.sender`\n DSU.pull(msg.sender, amount);\n\n // Deposit the amount to the collateral account\n collateral.depositTo(account, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account to `receiver`\n * @param receiver address to withdraw funds on behalf of msg.sender to\n * @param product Product to withdraw frunds from\n * @param amount Amount of DSU to withdraw out of the collateral account\n */\n function _withdraw(address receiver, IProduct product, UFixed18 amount) internal {\n collateral.withdrawFrom(msg.sender, receiver, IProduct(product), amount);\n }\n\n /**\n * @notice Claim `msg.sender`s incentive reward for `product` programs\n * @param product Product to claim\n */\n function _claim(IProduct product, uint256[] memory programIds) internal {\n controller.incentivizer().claimFor(msg.sender, product, programIds);\n }\n\n /**\n * @notice Wraps `amount` USDC into DSU, pulling from `msg.sender` and sending to `receiver`\n * @param receiver Address to receive the DSU\n * @param amount Amount of USDC to wrap\n */\n function _wrap(address receiver, UFixed18 amount) internal {\n // Pull USDC from the `msg.sender`\n USDC.pull(msg.sender, amount, true);\n\n _handleWrap(receiver, amount);\n }\n\n /**\n * @notice Unwraps `amount` DSU into USDC, pulling from `msg.sender` and sending to `receiver`\n * @param receiver Address to receive the USDC\n * @param amount Amount of DSU to unwrap\n */\n function _unwrap(address receiver, UFixed18 amount) internal {\n // Pull the token from the `msg.sender`\n DSU.pull(msg.sender, amount);\n\n _handleUnwrap(receiver, amount);\n }\n\n /**\n * @notice Wraps `amount` USDC from `msg.sender` into DSU, then deposits the USDC into `account`s `product` collateral account\n * @param account Account to deposit funds on behalf of\n * @param product Product to deposit funds for\n * @param amount Amount of USDC to deposit into the collateral account\n */\n function _wrapAndDeposit(address account, IProduct product, UFixed18 amount) internal {\n // Pull USDC from the `msg.sender`\n USDC.pull(msg.sender, amount, true);\n\n _wrap(address(this), amount);\n\n // Deposit the amount to the collateral account\n collateral.depositTo(account, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account, then unwraps the DSU into USDC and sends it to `receiver`\n * @param receiver Address to receive the USDC\n * @param product Product to withdraw funds for\n * @param amount Amount of DSU to withdraw from the collateral account\n */\n function _withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) internal {\n // Withdraw the amount from the collateral account\n collateral.withdrawFrom(msg.sender, address(this), product, amount);\n\n _unwrap(receiver, amount);\n }\n\n /**\n * @notice Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account`\n * @param account Address to receive the vault shares\n * @param vault Vault to deposit funds into\n * @param amount Amount of DSU to deposit into the vault\n */\n function _vaultDeposit(address account, IPerennialVault vault, UFixed18 amount) internal {\n // Pull the DSU from the user\n DSU.pull(msg.sender, amount);\n\n // Just-in-time approval to the vault for the amount being deposited\n DSU.approve(address(vault), amount);\n\n // Deposit the DSU to the vault, crediting shares to `account`\n vault.deposit(amount, account);\n }\n\n /**\n * @notice Redeems `shares` shares from the vault on behalf of `msg.sender`\n * @dev Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets\n * If account is not msg.sender, requires prior spending approval\n * @param shares Amount of shares to redeem\n * @param vault Vault to redeem from\n */\n function _vaultRedeem(IPerennialVault vault, UFixed18 shares) internal {\n vault.redeem(shares, msg.sender);\n }\n\n /**\n * @notice Claims all claimable assets for account, sending assets to account\n * @param vault Vault to claim from\n * @param owner Account to claim for\n */\n function _vaultClaim(IPerennialVault vault, address owner) internal {\n vault.claim(owner);\n }\n\n /**\n * @notice Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault`\n * @param account Address to receive the vault shares\n * @param vault Vault to deposit funds into\n * @param amount Amount of USDC to wrap and deposit into the vault\n */\n function _vaultWrapAndDeposit(address account, IPerennialVault vault, UFixed18 amount) internal {\n // Pull USDC from the `msg.sender`\n USDC.pull(msg.sender, amount, true);\n\n _wrap(address(this), amount);\n\n // Just-in-time approval to the vault for the amount being deposited\n DSU.approve(address(vault), amount);\n\n // Deposit the DSU to the vault, crediting shares to `account`\n vault.deposit(amount, account);\n }\n\n /**\n * @notice Helper function to wrap `amount` USDC from `msg.sender` into DSU using the batcher or reserve\n * @param receiver Address to receive the DSU\n * @param amount Amount of USDC to wrap\n */\n function _handleWrap(address receiver, UFixed18 amount) internal {\n // If the batcher is 0 or doesn't have enough for this wrap, go directly to the reserve\n if (address(batcher) == address(0) || amount.gt(DSU.balanceOf(address(batcher)))) {\n reserve.mint(amount);\n if (receiver != address(this)) DSU.push(receiver, amount);\n } else {\n // Wrap the USDC into DSU and return to the receiver\n batcher.wrap(amount, receiver);\n }\n }\n\n /**\n * @notice Helper function to unwrap `amount` DSU into USDC and send to `receiver`\n * @param receiver Address to receive the USDC\n * @param amount Amount of DSU to unwrap\n */\n function _handleUnwrap(address receiver, UFixed18 amount) internal {\n // If the batcher is 0 or doesn't have enough for this unwrap, go directly to the reserve\n if (address(batcher) == address(0) || amount.gt(USDC.balanceOf(address(batcher)))) {\n reserve.redeem(amount);\n if (receiver != address(this)) USDC.push(receiver, amount);\n } else {\n // Unwrap the DSU into USDC and return to the receiver\n batcher.unwrap(amount, receiver);\n }\n }\n}\n" + }, + "contracts/multiinvoker/MultiInvokerRollup.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.15;\n\nimport \"./MultiInvoker.sol\";\nimport \"../interfaces/IMultiInvokerRollup.sol\";\n\n/// @title A calldata-optimized implementation of the Perennial MultiInvoker \n/// @notice Retains same functionality and `invoke` entry point from inherited MultiInvoker\ncontract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker {\n\n /// @dev the pointer struct for current decoding position in calldata to pass by reference\n struct PTR {\n uint256 pos;\n }\n\n /// @dev array of all stored addresses (users, products, vaults, etc) for calldata packing\n address[] public addressCache;\n /// @dev index lookup of above array for constructing calldata\n mapping(address => uint256) public addressLookup;\n\n constructor(Token6 usdc, IBatcher _batcher, IEmptySetReserve _reserve, IController _controller) \n MultiInvoker(usdc, _batcher, _reserve, _controller) \n { \n // an empty `addressLookup` resolves to 0\n // prevents a real address from colliding with 0 index\n _setAddressCache(address(0));\n }\n\n /// @dev fallback eliminates the need to include function sig in calldata\n fallback (bytes calldata input) external returns (bytes memory) {\n _decodeFallbackAndInvoke(input);\n return \"\";\n }\n\n /**\n * @notice this function serves exactly the same as invoke(Invocation[] memory invocations),\n * but includes logic to handle the highly packed calldata\n * Encoding Scheme:\n * [0:1] => uint action \n * [1:2] => uint length of current encoded type \n * [2:length] => current encoded type (see individual type decoding functions)\n */\n function _decodeFallbackAndInvoke(bytes calldata input) internal {\n PTR memory ptr = PTR(0);\n \n uint256 len = input.length;\n \n for (ptr.pos; ptr.pos < len;) {\n uint8 action = _toUint8(input, ptr);\n\n // solidity doesn't like evaluating bytes as enums :/ \n if (action == 1) { // DEPOSIT\n address account = _toAddress(input, ptr);\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _deposit(account, IProduct(product), amount);\n } else if (action == 2) { // WITHDRAW\n address receiver = _toAddress(input, ptr);\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _withdraw(receiver, IProduct(product), amount);\n } else if (action == 3) { // OPEN_TAKE\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _openTake(IProduct(product), amount); \n } else if (action == 4) { // CLOSE_TAKE\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _closeTake(IProduct(product), amount);\n } else if (action == 5) { // OPEN_MAKE \n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _openMake(IProduct(product), amount);\n } else if (action == 6) { // CLOSE_MAKE\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _closeMake(IProduct(product), amount);\n } else if (action == 7) { // CLAIM \n address product = _toAddress(input, ptr);\n uint256[] memory programIds = _toUintArray(input, ptr);\n\n _claim(IProduct(product), programIds);\n } else if (action == 8) { // WRAP \n address receiver = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _wrap(receiver, amount);\n } else if (action == 9) { // UNWRAP\n address receiver = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _unwrap(receiver, amount);\n } else if (action == 10) { // WRAP_AND_DEPOSIT\n address account = _toAddress(input, ptr);\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n \n _wrapAndDeposit(account, IProduct(product), amount);\n } else if (action == 11) { // WITHDRAW_AND_UNWRAP\n address receiver = _toAddress(input, ptr);\n address product = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _withdrawAndUnwrap(receiver, IProduct(product), amount);\n } else if (action == 12) { // VAULT_DEPOSIT\n address depositer = _toAddress(input, ptr);\n address vault = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _vaultDeposit(depositer, IPerennialVault(vault), amount);\n } else if (action == 13) { // VAULT_REDEEM\n address vault = _toAddress(input, ptr);\n UFixed18 shares = _toAmount(input, ptr);\n\n _vaultRedeem(IPerennialVault(vault), shares);\n } else if (action == 14) { // VAULT_CLAIM\n address owner = _toAddress(input, ptr);\n address vault = _toAddress(input, ptr);\n\n _vaultClaim(IPerennialVault(vault), owner);\n } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT \n address account = _toAddress(input, ptr);\n address vault = _toAddress(input, ptr);\n UFixed18 amount = _toAmount(input, ptr);\n\n _vaultWrapAndDeposit(account, IPerennialVault(vault), amount);\n }\n }\n }\n\n /// @notice Unchecked sets address in cache\n /// @param addr Address to add to cache \n function _setAddressCache(address addr) private {\n // index of address to be added to cache\n uint256 idx = addressCache.length;\n\n // set address and lookup table\n addressCache.push(addr);\n addressLookup[addr] = idx;\n\n emit AddressAddedToCache(addr, idx);\n }\n\n /**\n * @notice Helper function to get address from calldata\n * @param input Full calldata payload\n * @param ptr Current index of input to start decoding \n * @return addr The decoded address\n */\n function _toAddress(bytes calldata input, PTR memory ptr) private returns (address addr) {\n uint8 len = _toUint8(input, ptr);\n\n // user is new to registry, add next 20 bytes as address to registry and return address\n if (len == 0) {\n addr = _bytesToAddress(input[ptr.pos:ptr.pos+20]);\n ptr.pos += 20;\n\n _setAddressCache(addr);\n } else {\n uint256 addrNonceLookup = _bytesToUint256(input[ptr.pos:ptr.pos+len]);\n ptr.pos += len;\n\n addr = _getAddressCache(addrNonceLookup);\n }\n }\n\n /**\n * @notice Checked gets the address in cache mapped to the cache index\n * @dev There is an issue with the calldata if a txn uses cache before caching address\n * @param idx The cache index\n * @return addr Address stored at cache index\n */\n function _getAddressCache(uint256 idx) private view returns (address addr){\n addr = addressCache[idx];\n if (addr == address(0)) revert MultiInvokerRollupInvalidCalldataError();\n }\n\n /**\n * @notice Wraps next length of bytes as UFixed18\n * @param input Full calldata payload\n * @param ptr Current index of input to start decoding\n * @param ptr Current index of input to start decoding\n */\n function _toAmount(bytes calldata input, PTR memory ptr) private view returns (UFixed18 result) {\n return UFixed18.wrap(_toUint256(input, ptr));\n }\n\n /**\n * @notice Unpacks next length of bytes as lengths of bytes into array of uint256\n * @param input Full calldata payload\n * @param ptr Current index of input to start decoding\n * @return ProgramIds for CLAIM action \n */\n function _toUintArray(bytes calldata input, PTR memory ptr) private pure returns (uint256[] memory) {\n uint8 arrayLen = _toUint8(input, ptr);\n\n uint256[] memory result = new uint256[](arrayLen);\n\n for (uint256 count; count < arrayLen;) {\n uint256 currUint;\n\n currUint = _toUint256(input, ptr);\n\n result[count] = currUint;\n\n ++count;\n }\n return result;\n }\n\n /**\n * @dev This is called in decodeAccount and decodeProduct which both only pass 20 byte slices \n * @notice Unchecked force of 20 bytes into address\n * @param input The 20 bytes to be converted to address\n * @return addr Address representation of `input`\n */\n function _bytesToAddress(bytes memory input) private pure returns (address addr) {\n assembly {\n addr := mload(add(input, 20))\n } \n }\n\n /**\n * @notice Helper function to get uint8 length from calldata\n * @param input Full calldata payload\n * @param ptr Current index of input to start decoding \n * @return res The decoded uint8 length\n */\n function _toUint8(bytes calldata input, PTR memory ptr) private pure returns (uint8 res) {\n res = _bytesToUint8(input[ptr.pos:ptr.pos+1]);\n ++ptr.pos;\n }\n\n /**\n * @notice Implementation of GNSPS' standard BytesLib.sol\n * @param input 1 byte slice to convert to uint8 to decode lengths\n * @return res The uint8 representation of input\n */\n function _bytesToUint8(bytes memory input) private pure returns (uint8 res) {\n assembly {\n res := mload(add(input, 0x1))\n }\n }\n\n /**\n * @notice Helper function to get uint256 from calldata\n * @param input Full calldata payload\n * @param ptr Current index of input to start decoding \n * @return res The decoded uint256\n */\n function _toUint256(bytes calldata input, PTR memory ptr) private pure returns (uint256 res) {\n uint8 len = _toUint8(input, ptr);\n\n res = _bytesToUint256(input[ptr.pos:ptr.pos+len]);\n ptr.pos += len;\n }\n\n /** \n * @notice Unchecked loads arbitrarily-sized bytes into a uint\n * @dev Bytes length enforced as < max word size\n * @param input The bytes to convert to uint256\n * @return res The resulting uint256\n */\n function _bytesToUint256(bytes memory input) private pure returns (uint256 res) {\n uint256 len = input.length;\n\n // length must not exceed max bytes length of a word/uint\n if (len > 32) revert MultiInvokerRollupInvalidCalldataError();\n\n assembly {\n res := mload(add(input, 0x20))\n }\n\n // readable right shift to change right padding of mload to left padding\n res >>= 256 - (len * 8);\n }\n}" + }, + "contracts/product/types/accumulator/AccountAccumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/types/Accumulator.sol\";\nimport \"../position/AccountPosition.sol\";\nimport \"./VersionedAccumulator.sol\";\n\n/// @dev AccountAccumulator type\nstruct AccountAccumulator {\n /// @dev latest version that the account was synced too\n uint256 latestVersion;\n}\nusing AccountAccumulatorLib for AccountAccumulator global;\n\n/**\n * @title AccountAccumulatorLib\n * @notice Library that manages syncing an account-level accumulator.\n */\nlibrary AccountAccumulatorLib {\n /**\n * @notice Syncs the account to oracle version `versionTo`\n * @param self The struct to operate on\n * @param global Pointer to global accumulator\n * @param position Pointer to global position\n * @param versionTo Oracle version to sync account to\n * @return value The value accumulated sync last sync\n */\n function syncTo(\n AccountAccumulator storage self,\n VersionedAccumulator storage global,\n AccountPosition storage position,\n uint256 versionTo\n ) internal returns (Accumulator memory value) {\n Accumulator memory valueAccumulated = global.valueAtVersion(versionTo)\n .sub(global.valueAtVersion(self.latestVersion));\n value = position.position.mul(valueAccumulated);\n self.latestVersion = versionTo;\n }\n}\n" + }, + "contracts/product/types/accumulator/VersionedAccumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/IProduct.sol\";\nimport \"../../../interfaces/types/Accumulator.sol\";\nimport \"../position/VersionedPosition.sol\";\n\n/// @dev VersionedAccumulator type\nstruct VersionedAccumulator {\n /// @dev Latest synced oracle version\n uint256 latestVersion;\n\n /// @dev Mapping of accumulator value at each settled oracle version\n mapping(uint256 => PackedAccumulator) _valueAtVersion;\n\n /// @dev Mapping of accumulator share at each settled oracle version\n mapping(uint256 => PackedAccumulator) _shareAtVersion;\n}\nusing VersionedAccumulatorLib for VersionedAccumulator global;\n\n/**\n * @title VersionedAccumulatorLib\n * @notice Library that manages global versioned accumulator state.\n * @dev Manages two accumulators: value and share. The value accumulator measures the change in position value\n * over time. The share accumulator measures the change in liquidity ownership over time (for tracking\n * incentivization rewards).\n *\n * Both accumulators are stamped for historical lookup anytime there is a global settlement, which services\n * the delayed-position accounting. It is not guaranteed that every version will have a value stamped, but\n * only versions when a settlement occurred are needed for this historical computation.\n */\nlibrary VersionedAccumulatorLib {\n /**\n * @notice Returns the stamped value accumulator at `oracleVersion`\n * @param self The struct to operate on\n * @param oracleVersion The oracle version to retrieve the value at\n * @return The stamped value accumulator at the requested version\n */\n function valueAtVersion(VersionedAccumulator storage self, uint256 oracleVersion) internal view returns (Accumulator memory) {\n return self._valueAtVersion[oracleVersion].unpack();\n }\n\n /**\n * @notice Returns the stamped share accumulator at `oracleVersion`\n * @param self The struct to operate on\n * @param oracleVersion The oracle version to retrieve the share at\n * @return The stamped share accumulator at the requested version\n */\n function shareAtVersion(VersionedAccumulator storage self, uint256 oracleVersion) internal view returns (Accumulator memory) {\n return self._shareAtVersion[oracleVersion].unpack();\n }\n\n /**\n * @notice Globally accumulates all value (position + funding) and share since last oracle update\n * @param self The struct to operate on\n * @param fundingFee The funding fee rate for the product\n * @param position Pointer to global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedFee The total fee accrued from accumulation\n */\n function accumulate(\n VersionedAccumulator storage self,\n UFixed18 fundingFee,\n VersionedPosition storage position,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal returns (UFixed18 accumulatedFee) {\n Position memory latestPosition = position.positionAtVersion(latestOracleVersion.version);\n\n // accumulate funding\n Accumulator memory accumulatedPosition;\n (accumulatedPosition, accumulatedFee) =\n _accumulateFunding(fundingFee, latestPosition, latestOracleVersion, toOracleVersion);\n\n // accumulate position\n accumulatedPosition = accumulatedPosition.add(\n _accumulatePosition(latestPosition, latestOracleVersion, toOracleVersion));\n\n // accumulate position fee\n (Accumulator memory accumulatedPositionFee, UFixed18 protocolPositionFee) =\n _accumulatePositionFee(latestPosition, position.pre, latestOracleVersion);\n accumulatedPosition = accumulatedPosition.add(accumulatedPositionFee);\n accumulatedFee = accumulatedFee.add(protocolPositionFee);\n\n // accumulate share\n Accumulator memory accumulatedShare =\n _accumulateShare(latestPosition, latestOracleVersion, toOracleVersion);\n\n // save update\n self._valueAtVersion[toOracleVersion.version] = valueAtVersion(self, latestOracleVersion.version)\n .add(accumulatedPosition)\n .pack();\n self._shareAtVersion[toOracleVersion.version] = shareAtVersion(self, latestOracleVersion.version)\n .add(accumulatedShare)\n .pack();\n self.latestVersion = toOracleVersion.version;\n }\n\n /**\n * @notice Globally accumulates all funding since last oracle update\n * @dev If an oracle version is skipped due to no pre positions, funding will continue to be\n * pegged to the price of the last snapshotted oracleVersion until a new one is accumulated.\n * This is an acceptable approximation.\n * @param fundingFee The funding fee rate for the product\n * @param latestPosition The latest global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedFunding The total amount accumulated from funding\n * @return accumulatedFee The total fee accrued from funding accumulation\n */\n function _accumulateFunding(\n UFixed18 fundingFee,\n Position memory latestPosition,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) private view returns (Accumulator memory accumulatedFunding, UFixed18 accumulatedFee) {\n if (_product().closed()) return (Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO), UFixed18Lib.ZERO);\n if (latestPosition.taker.isZero()) return (Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO), UFixed18Lib.ZERO);\n if (latestPosition.maker.isZero()) return (Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO), UFixed18Lib.ZERO);\n\n uint256 elapsed = toOracleVersion.timestamp - latestOracleVersion.timestamp;\n\n UFixed18 takerNotional = Fixed18Lib.from(latestPosition.taker).mul(latestOracleVersion.price).abs();\n UFixed18 socializedNotional = takerNotional.mul(latestPosition.socializationFactor());\n\n Fixed18 rateAccumulated = _product().rate(latestPosition)\n .mul(Fixed18Lib.from(UFixed18Lib.from(elapsed)));\n Fixed18 fundingAccumulated = rateAccumulated.mul(Fixed18Lib.from(socializedNotional));\n accumulatedFee = fundingAccumulated.abs().mul(fundingFee);\n\n Fixed18 fundingAccumulatedWithoutFee = Fixed18Lib.from(\n fundingAccumulated.sign(),\n fundingAccumulated.abs().sub(accumulatedFee)\n );\n\n bool makerPaysFunding = fundingAccumulated.sign() < 0;\n accumulatedFunding.maker = (makerPaysFunding ? fundingAccumulated : fundingAccumulatedWithoutFee)\n .div(Fixed18Lib.from(latestPosition.maker));\n accumulatedFunding.taker = (makerPaysFunding ? fundingAccumulatedWithoutFee : fundingAccumulated)\n .div(Fixed18Lib.from(latestPosition.taker)).mul(Fixed18Lib.NEG_ONE);\n }\n\n /**\n * @notice Globally accumulates position PNL since last oracle update\n * @param latestPosition The latest global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedPosition The total amount accumulated from position PNL\n */\n function _accumulatePosition(\n Position memory latestPosition,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) private view returns (Accumulator memory accumulatedPosition) {\n if (_product().closed()) return Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO);\n if (latestPosition.taker.isZero()) return Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO);\n if (latestPosition.maker.isZero()) return Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO);\n\n Fixed18 oracleDelta = toOracleVersion.price.sub(latestOracleVersion.price);\n Fixed18 totalTakerDelta = oracleDelta.mul(Fixed18Lib.from(latestPosition.taker));\n Fixed18 socializedTakerDelta = totalTakerDelta.mul(Fixed18Lib.from(latestPosition.socializationFactor()));\n\n accumulatedPosition.maker = socializedTakerDelta.div(Fixed18Lib.from(latestPosition.maker)).mul(Fixed18Lib.NEG_ONE);\n accumulatedPosition.taker = socializedTakerDelta.div(Fixed18Lib.from(latestPosition.taker));\n }\n\n /**\n * @notice Globally accumulates position fees since last oracle update\n * @dev Position fees are calculated based on the price at `latestOracleVersion` as that is the price used to\n * calculate the user's fee total. In the event that settlement is occurring over multiple oracle versions\n * (i.e. from a -> b -> c) it is safe to use the latestOracleVersion because in the a -> b case, a is always\n * b - 1, and in the b -> c case the `PrePosition` is always empty so this is skipped.\n * @param latestPosition The latest global position\n * @param pre The global pre-position\n * @param latestOracleVersion The latest oracle version\n * @return accumulatedPosition The total amount accumulated from position PNL\n * @return fee The position fee that is retained by the protocol and product\n */\n function _accumulatePositionFee(\n Position memory latestPosition,\n PrePosition memory pre,\n IOracleProvider.OracleVersion memory latestOracleVersion\n ) private view returns (Accumulator memory accumulatedPosition, UFixed18 fee) {\n if (pre.isEmpty()) return (accumulatedPosition, fee);\n\n Position memory positionFee = pre.computeFee(latestOracleVersion);\n Position memory protocolFee = positionFee.mul(_product().positionFee());\n positionFee = positionFee.sub(protocolFee);\n fee = protocolFee.sum();\n\n // If there are makers to distribute the taker's position fee to, distribute. Otherwise give it to the protocol\n if (!latestPosition.maker.isZero()) {\n accumulatedPosition.maker = Fixed18Lib.from(positionFee.taker.div(latestPosition.maker));\n } else {\n fee = fee.add(positionFee.taker);\n }\n\n // If there are takers to distribute the maker's position fee to, distribute. Otherwise give it to the protocol\n if (!latestPosition.taker.isZero()) {\n accumulatedPosition.taker = Fixed18Lib.from(positionFee.maker.div(latestPosition.taker));\n } else {\n fee = fee.add(positionFee.maker);\n }\n }\n\n /**\n * @notice Globally accumulates position's share of the total market since last oracle update\n * @dev This is used to compute incentivization rewards based on market participation\n * @param latestPosition The latest global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedShare The total share amount accumulated per position\n */\n function _accumulateShare(\n Position memory latestPosition,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) private pure returns (Accumulator memory accumulatedShare) {\n uint256 elapsed = toOracleVersion.timestamp - latestOracleVersion.timestamp;\n\n accumulatedShare.maker = latestPosition.maker.isZero() ?\n Fixed18Lib.ZERO :\n Fixed18Lib.from(UFixed18Lib.from(elapsed).div(latestPosition.maker));\n accumulatedShare.taker = latestPosition.taker.isZero() ?\n Fixed18Lib.ZERO :\n Fixed18Lib.from(UFixed18Lib.from(elapsed).div(latestPosition.taker));\n }\n\n function _product() private view returns (IProduct) {\n return IProduct(address(this));\n }\n}\n" + }, + "contracts/product/types/position/AccountPosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/IProduct.sol\";\nimport \"../../../interfaces/types/PrePosition.sol\";\n\n/// @dev AccountPosition type\nstruct AccountPosition {\n /// @dev The current settled position of the account\n Position position;\n\n /// @dev The current position delta pending-settlement\n PrePosition pre;\n\n /// @dev Whether the account is currently locked for liquidation\n bool liquidation;\n}\nusing AccountPositionLib for AccountPosition global;\n\n/**\n * @title AccountPositionLib\n * @notice Library that manages an account-level position.\n */\nlibrary AccountPositionLib {\n /**\n * @notice Settled the account's position to oracle version `toOracleVersion`\n * @param self The struct to operate on\n * @param toOracleVersion The oracle version to accumulate to\n */\n function settle(\n AccountPosition storage self,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal {\n bool settled;\n (self.position, settled) = self.position.settled(self.pre, toOracleVersion);\n if (settled) {\n delete self.pre;\n self.liquidation = false;\n }\n }\n\n /**\n * @notice Returns the current maintenance requirement for the account\n * @dev Must be called from a valid product to get the proper maintenance value\n * @param self The struct to operate on\n * @return Current maintenance requirement for the account\n */\n function maintenance(AccountPosition storage self) internal view returns (UFixed18) {\n return _maintenance(self.position);\n }\n\n /**\n * @notice Returns the maintenance requirement after the next oracle version settlement\n * @dev Includes the current pending-settlement position delta, assumes no price change\n * @param self The struct to operate on\n * @return Next maintenance requirement for the account\n */\n function maintenanceNext(AccountPosition storage self) internal view returns (UFixed18) {\n return _maintenance(self.position.next(self.pre));\n }\n\n /**\n * @notice Returns the maintenance requirement for a given `position`\n * @dev Internal helper\n * @param position The position to compete the maintenance requirement for\n * @return Next maintenance requirement for the account\n */\n function _maintenance(Position memory position) private view returns (UFixed18) {\n IProduct product = IProduct(address(this));\n Fixed18 oraclePrice = product.currentVersion().price;\n UFixed18 notionalMax = Fixed18Lib.from(position.max()).mul(oraclePrice).abs();\n return notionalMax.mul(product.maintenance());\n }\n\n /**\n * @notice Returns whether an account is completely closed, i.e. no position or pre-position\n * @param self The struct to operate on\n * @return Whether the account is closed\n */\n function isClosed(AccountPosition memory self) internal pure returns (bool) {\n return self.pre.isEmpty() && self.position.isEmpty();\n }\n\n /**\n * @notice Returns whether an account has opened position on both sides of the market (maker vs taker)\n * @dev Used to verify the invariant that a single account can only have a position on one side of the\n * market at a time\n * @param self The struct to operate on\n * @return Whether the account is currently doubled sided\n */\n function isDoubleSided(AccountPosition storage self) internal view returns (bool) {\n bool makerEmpty = self.position.maker.isZero() && self.pre.openPosition.maker.isZero() && self.pre.closePosition.maker.isZero();\n bool takerEmpty = self.position.taker.isZero() && self.pre.openPosition.taker.isZero() && self.pre.closePosition.taker.isZero();\n\n return !makerEmpty && !takerEmpty;\n }\n\n /**\n * @notice Returns whether the account's pending-settlement delta closes more position than is open\n * @dev Used to verify the invariant that an account cannot settle into having a negative position\n * @param self The struct to operate on\n * @return Whether the account is currently over closed\n */\n function isOverClosed(AccountPosition storage self) internal view returns (bool) {\n Position memory nextOpen = self.position.add(self.pre.openPosition);\n\n return self.pre.closePosition.maker.gt(nextOpen.maker) || self.pre.closePosition.taker.gt(nextOpen.taker);\n }\n}\n" + }, + "contracts/product/types/position/VersionedPosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/types/PrePosition.sol\";\nimport \"../../../interfaces/types/PackedPosition.sol\";\n\n//// @dev VersionedPosition type\nstruct VersionedPosition {\n /// @dev Mapping of global position at each version\n mapping(uint256 => PackedPosition) _positionAtVersion;\n\n /// @dev Current global pending-settlement position delta\n PrePosition pre;\n}\nusing VersionedPositionLib for VersionedPosition global;\n\n/**\n * @title VersionedPositionLib\n * @notice Library that manages global position state.\n * @dev Global position state is used to compute utilization rate and socialization, and to account for and\n * distribute fees globally.\n *\n * Positions are stamped for historical lookup anytime there is a global settlement, which services\n * the delayed-position accounting. It is not guaranteed that every version will have a value stamped, but\n * only versions when a settlement occurred are needed for this historical computation.\n */\nlibrary VersionedPositionLib {\n /**\n * @notice Returns the current global position\n * @return Current global position\n */\n function positionAtVersion(VersionedPosition storage self, uint256 oracleVersion) internal view returns (Position memory) {\n return self._positionAtVersion[oracleVersion].unpack();\n }\n\n /**\n * @notice Settled the global position to oracle version `toOracleVersion`\n * @param self The struct to operate on\n * @param latestVersion The latest settled oracle version\n * @param toOracleVersion The oracle version to settle to\n */\n function settle(\n VersionedPosition storage self,\n uint256 latestVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal {\n (Position memory newPosition, bool settled) =\n positionAtVersion(self, latestVersion).settled(self.pre, toOracleVersion);\n\n self._positionAtVersion[toOracleVersion.version] = newPosition.pack();\n if (settled) delete self.pre;\n }\n}\n" + }, + "contracts/product/UParamProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"../controller/UControllerProvider.sol\";\nimport \"../interfaces/IParamProvider.sol\";\nimport \"../interfaces/IProduct.sol\";\nimport \"../interfaces/types/PendingFeeUpdates.sol\";\n\n/**\n * @title UParamProvider\n * @notice Library for manage storing, surfacing, and upgrading a product's parameters.\n * @dev Uses an unstructured storage pattern to store the parameters which allows this\n provider to be safely used with upgradeable contracts. For certain paramters, a\n staged update pattern is used.\n */\nabstract contract UParamProvider is IParamProvider, UControllerProvider {\n /**\n * @notice Initializes the contract state\n * @param maintenance_ product maintenance ratio\n * @param fundingFee_ product funding fee\n * @param makerFee_ product maker fee\n * @param takerFee_ product taker fee\n * @param makerLimit_ product maker limit\n * @param utilizationCurve_ utilization curve definition\n */\n // solhint-disable-next-line func-name-mixedcase\n function __UParamProvider__initialize(\n UFixed18 maintenance_,\n UFixed18 fundingFee_,\n UFixed18 makerFee_,\n UFixed18 takerFee_,\n UFixed18 positionFee_,\n UFixed18 makerLimit_,\n JumpRateUtilizationCurve memory utilizationCurve_\n ) internal onlyInitializer {\n _updateMaintenance(maintenance_);\n _updateFundingFee(fundingFee_);\n _updateMakerFee(makerFee_);\n _updateTakerFee(takerFee_);\n _updatePositionFee(positionFee_);\n _updateMakerLimit(makerLimit_);\n _updateUtilizationCurve(utilizationCurve_);\n }\n\n /// @dev The maintenance value\n UFixed18Storage private constant _maintenance = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.maintenance\"));\n function maintenance() public view returns (UFixed18) { return _maintenance.read(); }\n\n /// @dev The funding fee value\n UFixed18Storage private constant _fundingFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.fundingFee\"));\n function fundingFee() public view returns (UFixed18) { return _fundingFee.read(); }\n\n /// @dev The maker fee value\n UFixed18Storage private constant _makerFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.makerFee\"));\n function makerFee() public view returns (UFixed18) { return _makerFee.read(); }\n\n /// @dev The taker fee value\n UFixed18Storage private constant _takerFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.takerFee\"));\n function takerFee() public view returns (UFixed18) { return _takerFee.read(); }\n\n /// @dev The positon fee share value\n UFixed18Storage private constant _positionFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.positionFee\"));\n function positionFee() public view returns (UFixed18) { return _positionFee.read(); }\n\n /// @dev The maker limit value\n UFixed18Storage private constant _makerLimit = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.makerLimit\"));\n function makerLimit() public view returns (UFixed18) { return _makerLimit.read(); }\n\n /// @dev The JumpRateUtilizationCurve params\n JumpRateUtilizationCurveStorage private constant _utilizationCurve =\n JumpRateUtilizationCurveStorage.wrap(keccak256(\"equilibria.perennial.UParamProvider.jumpRateUtilizationCurve\"));\n function utilizationCurve() public view returns (JumpRateUtilizationCurve memory) { return _utilizationCurve.read(); }\n\n /// @dev The pending fee updates value\n PendingFeeUpdatesStorage private constant _pendingFeeUpdates =\n PendingFeeUpdatesStorage.wrap(keccak256(\"equilibria.perennial.UParamProvider.pendingFeeUpdates\"));\n function pendingFeeUpdates() public view returns (PendingFeeUpdates memory) { return _pendingFeeUpdates.read(); }\n\n /**\n * @notice Updates the maintenance to `newMaintenance`\n * @param newMaintenance new maintenance value\n */\n function _updateMaintenance(UFixed18 newMaintenance) private {\n _maintenance.store(newMaintenance);\n emit MaintenanceUpdated(newMaintenance, _productVersion());\n }\n\n /**\n * @notice Updates the maintenance to `newMaintenance`\n * @dev only callable by product owner\n * @param newMaintenance new maintenance value\n */\n function updateMaintenance(UFixed18 newMaintenance) external onlyProductOwner settleProduct {\n _updateMaintenance(newMaintenance);\n }\n\n /**\n * @notice Updates the funding fee to `newFundingFee`\n * @param newFundingFee new funding fee value\n */\n function _updateFundingFee(UFixed18 newFundingFee) private {\n if (newFundingFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _fundingFee.store(newFundingFee);\n emit FundingFeeUpdated(newFundingFee, _productVersion());\n }\n\n /**\n * @notice Updates the funding fee to `newFundingFee`\n * @dev only callable by product owner\n * @param newFundingFee new funding fee value\n */\n function updateFundingFee(UFixed18 newFundingFee) external onlyProductOwner settleProduct {\n _updateFundingFee(newFundingFee);\n }\n\n /**\n * @notice Updates the maker fee to `newMakerFee`\n * @param newMakerFee new maker fee value\n */\n function _updateMakerFee(UFixed18 newMakerFee) private {\n if (newMakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _makerFee.store(newMakerFee);\n emit MakerFeeUpdated(newMakerFee, _productVersion());\n }\n\n /**\n * @notice Updates the pending maker fee to `newMakerFee`\n * @param newMakerFee new maker fee value\n */\n function _updatePendingMakerFee(UFixed18 newMakerFee) private {\n if (newMakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n PendingFeeUpdates memory pendingFees_ = pendingFeeUpdates();\n pendingFees_.updateMakerFee(newMakerFee);\n _pendingFeeUpdates.store(pendingFees_);\n emit PendingMakerFeeUpdated(newMakerFee);\n }\n\n /**\n * @notice Updates the maker fee to `newMakerFee`\n * @dev only callable by product owner\n * @param newMakerFee new maker fee value\n */\n function updateMakerFee(UFixed18 newMakerFee) external onlyProductOwner settleProduct {\n if (!_noPendingPositions()) {\n _updatePendingMakerFee(newMakerFee);\n } else {\n _updateMakerFee(newMakerFee);\n }\n }\n\n /**\n * @notice Updates the taker fee to `newTakerFee`\n * @param newTakerFee new taker fee value\n */\n function _updateTakerFee(UFixed18 newTakerFee) private {\n if (newTakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _takerFee.store(newTakerFee);\n emit TakerFeeUpdated(newTakerFee, _productVersion());\n }\n\n /**\n * @notice Updates the pending taker fee to `newTakerFee`\n * @param newTakerFee new taker fee value\n */\n function _updatePendingTakerFee(UFixed18 newTakerFee) private {\n if (newTakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n PendingFeeUpdates memory pendingFees_ = pendingFeeUpdates();\n pendingFees_.updateTakerFee(newTakerFee);\n _pendingFeeUpdates.store(pendingFees_);\n emit PendingTakerFeeUpdated(newTakerFee);\n }\n\n /**\n * @notice Updates the taker fee to `newTakerFee`\n * @dev only callable by product owner\n * @param newTakerFee new taker fee value\n */\n function updateTakerFee(UFixed18 newTakerFee) external onlyProductOwner settleProduct {\n if (!_noPendingPositions()) {\n _updatePendingTakerFee(newTakerFee);\n } else {\n _updateTakerFee(newTakerFee);\n }\n }\n\n /**\n * @notice Updates the position fee to `newPositionFee`\n * @param newPositionFee new position fee value\n */\n function _updatePositionFee(UFixed18 newPositionFee) private {\n if (newPositionFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _positionFee.store(newPositionFee);\n emit PositionFeeUpdated(newPositionFee, _productVersion());\n }\n\n /**\n * @notice Updates the pending position fee to `newPositionFee`\n * @param newPositionFee new position fee value\n */\n function _updatePendingPositionFee(UFixed18 newPositionFee) private {\n if (newPositionFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n PendingFeeUpdates memory pendingFees_ = pendingFeeUpdates();\n pendingFees_.updatePositionFee(newPositionFee);\n _pendingFeeUpdates.store(pendingFees_);\n emit PendingPositionFeeUpdated(newPositionFee);\n }\n\n /**\n * @notice Updates the position fee to `newPositionFee`\n * @dev only callable by product owner\n * @param newPositionFee new position fee value\n */\n function updatePositionFee(UFixed18 newPositionFee) external onlyProductOwner settleProduct {\n if (!_noPendingPositions()) {\n _updatePendingPositionFee(newPositionFee);\n } else {\n _updatePositionFee(newPositionFee);\n }\n }\n\n /**\n * @notice Updates the maker limit to `newMakerLimit`\n * @param newMakerLimit new maker limit value\n */\n function _updateMakerLimit(UFixed18 newMakerLimit) private {\n _makerLimit.store(newMakerLimit);\n emit MakerLimitUpdated(newMakerLimit, _productVersion());\n }\n\n /**\n * @notice Updates the maker limit to `newMakerLimit`\n * @dev only callable by product owner\n * @param newMakerLimit new maker limit value\n */\n function updateMakerLimit(UFixed18 newMakerLimit) external onlyProductOwner settleProduct {\n _updateMakerLimit(newMakerLimit);\n }\n\n /**\n * @notice Updates the utilization curve to `newUtilizationCurve`\n * @param newUtilizationCurve new utilization curve value\n */\n function _updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) private {\n _utilizationCurve.store(newUtilizationCurve);\n emit JumpRateUtilizationCurveUpdated(newUtilizationCurve, _productVersion());\n }\n\n /**\n * @notice Updates the utilization curve to `newUtilizationCurve`\n * @dev only callable by product owner\n * @param newUtilizationCurve new utilization curve value\n */\n function updateUtilizationCurve(JumpRateUtilizationCurve calldata newUtilizationCurve) external onlyProductOwner settleProduct {\n _updateUtilizationCurve(newUtilizationCurve);\n }\n\n function _settleFeeUpdates() internal {\n PendingFeeUpdates memory pendingFeeUpdates_ = pendingFeeUpdates();\n if (!pendingFeeUpdates_.hasUpdates()) return;\n if (pendingFeeUpdates_.makerFeeUpdated) _updateMakerFee(pendingFeeUpdates_.makerFee());\n if (pendingFeeUpdates_.takerFeeUpdated) _updateTakerFee(pendingFeeUpdates_.takerFee());\n if (pendingFeeUpdates_.positionFeeUpdated) _updatePositionFee(pendingFeeUpdates_.positionFee());\n\n pendingFeeUpdates_.clear();\n _pendingFeeUpdates.store(pendingFeeUpdates_);\n }\n\n function _productVersion() private view returns (uint256) {\n // If this product is being constructed then return 0\n if (!Address.isContract(address(this))) return 0;\n return IProduct(address(this)).latestVersion();\n }\n\n /**\n * @notice Checks whether the Product's `pre` position is empty\n * @return Whether or not the pre position is empty\n */\n function _noPendingPositions() private view returns (bool) {\n return IProduct(address(this)).pre().isEmpty();\n }\n\n /// @dev Only allow the Product's coordinator owner to call\n modifier onlyProductOwner {\n uint256 coordinatorId = controller().coordinatorFor(IProduct(address(this)));\n if (controller().owner(coordinatorId) != msg.sender) revert NotOwnerError(coordinatorId);\n\n _;\n }\n\n /// @dev Settles the product\n modifier settleProduct {\n IProduct(address(this)).settle();\n\n _;\n }\n}\n" + }, + "contracts/product/UPayoffProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"@equilibria/root/storage/UStorage.sol\";\nimport \"../interfaces/IPayoffProvider.sol\";\nimport \"../interfaces/types/PayoffDefinition.sol\";\n\n/**\n * @title UPayoffProvider\n * @notice Library for manage storing, surfacing, and upgrading a payoff provider.\n * @dev Uses an unstructured storage pattern to store the oracle address and payoff definition which allows this\n provider to be safely used with upgradeable contracts.\n */\nabstract contract UPayoffProvider is IPayoffProvider, UInitializable {\n /// @dev The oracle contract address\n AddressStorage private constant _oracle =\n AddressStorage.wrap(keccak256(\"equilibria.perennial.UPayoffProvider.oracle\"));\n function oracle() public view returns (IOracleProvider) { return IOracleProvider(_oracle.read()); }\n\n /// @dev Payoff definition struct\n PayoffDefinitionStorage private constant _payoffDefinition =\n PayoffDefinitionStorage.wrap(keccak256(\"equilibria.perennial.UPayoffProvider.payoffDefinition\"));\n function payoffDefinition() public view returns (PayoffDefinition memory) { return _payoffDefinition.read(); }\n\n /**\n * @notice Initializes the contract state\n * @param oracle_ Oracle address\n * @param payoffDefinition_ Payoff provider\n */\n // solhint-disable-next-line func-name-mixedcase\n function __UPayoffProvider__initialize(IOracleProvider oracle_, PayoffDefinition calldata payoffDefinition_) internal onlyInitializer {\n _updateOracle(address(oracle_), 0);\n\n if (!payoffDefinition_.valid()) revert PayoffProviderInvalidPayoffDefinitionError();\n _payoffDefinition.store(payoffDefinition_);\n }\n\n /**\n * @notice Returns the current oracle version transformed by the payoff definition\n * @return Current oracle version transformed by the payoff definition\n */\n function currentVersion() public view returns (IOracleProvider.OracleVersion memory) {\n return _transform(oracle().currentVersion());\n }\n\n /**\n * @notice Returns the oracle version at `oracleVersion` transformed by the payoff definition\n * @param oracleVersion Oracle version to return for\n * @return Oracle version at `oracleVersion` with price transformed by payoff function\n */\n function atVersion(uint256 oracleVersion) public view returns (IOracleProvider.OracleVersion memory) {\n return _transform(oracle().atVersion(oracleVersion));\n }\n\n /**\n * @notice Updates oracle to newOracle address\n * @param newOracle New oracle address\n * @param oracleVersion Oracle version of update\n */\n function _updateOracle(address newOracle, uint256 oracleVersion) internal {\n if (!Address.isContract(newOracle)) revert PayoffProviderInvalidOracle();\n _oracle.store(newOracle);\n\n emit OracleUpdated(newOracle, oracleVersion);\n }\n\n /**\n * @notice Hook to call sync() on the oracle provider and transform the resulting oracle version\n */\n function _sync() internal returns (IOracleProvider.OracleVersion memory) {\n return _transform(oracle().sync());\n }\n\n /**\n * @notice Returns the transformed oracle version\n * @param oracleVersion Oracle version to transform\n * @return Transformed oracle version\n */\n function _transform(IOracleProvider.OracleVersion memory oracleVersion)\n internal view virtual returns (IOracleProvider.OracleVersion memory) {\n oracleVersion.price = payoffDefinition().transform(oracleVersion.price);\n return oracleVersion;\n }\n}\n" + }, + "contracts/test/TestnetBatcher.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"./TestnetReserve.sol\";\n\ncontract TestnetBatcher is IBatcher {\n IEmptySetReserve public RESERVE;\n Token6 public USDC;\n Token18 public DSU;\n\n constructor(IEmptySetReserve reserve_, Token6 usdc_, Token18 dsu_) {\n RESERVE = reserve_;\n USDC = usdc_;\n DSU = dsu_;\n\n USDC.approve(address(RESERVE));\n DSU.approve(address(RESERVE));\n }\n\n function totalBalance() external pure returns (UFixed18) {\n return UFixed18Lib.MAX;\n }\n\n // Passthrough to Reserve\n function wrap(UFixed18 amount, address to) external {\n USDC.pull(msg.sender, amount, true);\n RESERVE.mint(amount);\n DSU.push(to, amount);\n\n emit Wrap(to, amount);\n }\n\n // Passthrough to Reserve\n function unwrap(UFixed18 amount, address to) external {\n DSU.pull(msg.sender, amount);\n RESERVE.redeem(amount);\n USDC.push(to, amount);\n\n emit Unwrap(to, amount);\n }\n\n // No-op\n function rebalance() external pure {\n return;\n }\n}\n" + }, + "contracts/test/TestnetDSU.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\ncontract TestnetDSU is ERC20, ERC20Burnable {\n uint256 private constant LIMIT = 1_000_000e18;\n\n address public minter;\n\n error TestnetDSUNotMinterError();\n error TestnetDSUOverLimitError();\n\n event TestnetDSUMinterUpdated(address indexed newMinter);\n\n constructor(address _minter) ERC20(\"Digital Standard Unit\", \"DSU\") {\n minter = _minter;\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n if (amount > LIMIT) revert TestnetDSUOverLimitError();\n\n _mint(account, amount);\n }\n\n function updateMinter(address newMinter) external onlyMinter {\n minter = newMinter;\n\n emit TestnetDSUMinterUpdated(newMinter);\n }\n\n modifier onlyMinter() {\n if (msg.sender != minter) revert TestnetDSUNotMinterError();\n _;\n }\n}\n" + }, + "contracts/test/TestnetProductProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\";\nimport \"../interfaces/IContractPayoffProvider.sol\";\n\ncontract TestnetContractPayoffProvider is IContractPayoffProvider {\n function payoff(Fixed18 price) public pure returns (Fixed18) {\n return price.mul(price);\n }\n}\n" + }, + "contracts/test/TestnetReserve.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\n\ncontract TestnetReserve is IEmptySetReserve {\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n constructor(Token18 dsu_, Token6 usdc_) {\n DSU = dsu_;\n USDC = usdc_;\n }\n\n function mint(UFixed18 amount) external {\n USDC.pull(msg.sender, amount, true);\n ERC20PresetMinterPauser(Token18.unwrap(DSU)).mint(msg.sender, UFixed18.unwrap(amount));\n\n uint256 pulledAmount = Math.ceilDiv(UFixed18.unwrap(amount), 1e12);\n emit Mint(msg.sender, UFixed18.unwrap(amount), pulledAmount);\n }\n\n function redeem(UFixed18 amount) external {\n DSU.pull(msg.sender, amount);\n ERC20Burnable(Token18.unwrap(DSU)).burn(UFixed18.unwrap(amount));\n USDC.push(msg.sender, amount, true);\n\n uint256 pushedAmount = UFixed18.unwrap(amount) / 1e12;\n emit Redeem(msg.sender, UFixed18.unwrap(amount), pushedAmount);\n }\n\n function debt(address) external pure returns (UFixed18) {\n return UFixed18Lib.ZERO;\n }\n\n function repay(address, UFixed18) external pure {\n return;\n }\n}\n" + }, + "contracts/test/TestnetUSDC.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\ncontract TestnetUSDC is ERC20, ERC20Burnable {\n // solhint-disable-next-line no-empty-blocks\n constructor() ERC20(\"USD Coin\", \"USDC\") { }\n\n function decimals() override public pure returns (uint8) {\n return 6;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n }\n}\n" + }, + "contracts/test/TestnetVault.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport { IPerennialVault } from \"../interfaces/IMultiInvoker.sol\";\n\ncontract TestnetVault is ERC20, IPerennialVault {\n Token18 public immutable asset;\n mapping(address => UFixed18) public claimable;\n\n uint256 private _version;\n\n constructor(Token18 _asset) ERC20(\"TestnetVaultToken\", \"TVT\") {\n asset = _asset;\n }\n\n function deposit(UFixed18 assets, address account) external {\n asset.pull(msg.sender, assets);\n\n _mint(account, UFixed18.unwrap(assets));\n\n emit Deposit(msg.sender, account, _version, assets);\n }\n\n function redeem(UFixed18 shares, address account) external {\n _burn(account, UFixed18.unwrap(shares));\n\n claimable[account] = claimable[account].add(shares);\n\n emit Redemption(msg.sender, account, _version, shares);\n }\n\n function claim(address owner) external {\n UFixed18 claimAmount = claimable[owner];\n claimable[owner] = UFixed18Lib.ZERO;\n asset.push(owner, claimAmount);\n\n emit Claim(msg.sender, owner, claimAmount);\n }\n\n function _incrementVersion() external {\n _version += 1;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/packages/perennial/deployments/arbitrumGoerli/solcInputs/d0dcdcd7c0b6f58f746ab3d6e5ce337c.json b/packages/perennial/deployments/arbitrumGoerli/solcInputs/d0dcdcd7c0b6f58f746ab3d6e5ce337c.json new file mode 100644 index 00000000..73438557 --- /dev/null +++ b/packages/perennial/deployments/arbitrumGoerli/solcInputs/d0dcdcd7c0b6f58f746ab3d6e5ce337c.json @@ -0,0 +1,423 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorInterface {\n function latestAnswer() external view returns (int256);\n\n function latestTimestamp() external view returns (uint256);\n\n function latestRound() external view returns (uint256);\n\n function getAnswer(uint256 roundId) external view returns (int256);\n\n function getTimestamp(uint256 roundId) external view returns (uint256);\n\n event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n\n event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}\n" + }, + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./AggregatorInterface.sol\";\nimport \"./AggregatorV3Interface.sol\";\n\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}\n" + }, + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n" + }, + "@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"./AggregatorV2V3Interface.sol\";\n\ninterface FeedRegistryInterface {\n struct Phase {\n uint16 phaseId;\n uint80 startingAggregatorRoundId;\n uint80 endingAggregatorRoundId;\n }\n\n event FeedProposed(\n address indexed asset,\n address indexed denomination,\n address indexed proposedAggregator,\n address currentAggregator,\n address sender\n );\n event FeedConfirmed(\n address indexed asset,\n address indexed denomination,\n address indexed latestAggregator,\n address previousAggregator,\n uint16 nextPhaseId,\n address sender\n );\n\n // V3 AggregatorV3Interface\n\n function decimals(address base, address quote) external view returns (uint8);\n\n function description(address base, address quote) external view returns (string memory);\n\n function version(address base, address quote) external view returns (uint256);\n\n function latestRoundData(address base, address quote)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function getRoundData(\n address base,\n address quote,\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n // V2 AggregatorInterface\n\n function latestAnswer(address base, address quote) external view returns (int256 answer);\n\n function latestTimestamp(address base, address quote) external view returns (uint256 timestamp);\n\n function latestRound(address base, address quote) external view returns (uint256 roundId);\n\n function getAnswer(\n address base,\n address quote,\n uint256 roundId\n ) external view returns (int256 answer);\n\n function getTimestamp(\n address base,\n address quote,\n uint256 roundId\n ) external view returns (uint256 timestamp);\n\n // Registry getters\n\n function getFeed(address base, address quote) external view returns (AggregatorV2V3Interface aggregator);\n\n function getPhaseFeed(\n address base,\n address quote,\n uint16 phaseId\n ) external view returns (AggregatorV2V3Interface aggregator);\n\n function isFeedEnabled(address aggregator) external view returns (bool);\n\n function getPhase(\n address base,\n address quote,\n uint16 phaseId\n ) external view returns (Phase memory phase);\n\n // Round helpers\n\n function getRoundFeed(\n address base,\n address quote,\n uint80 roundId\n ) external view returns (AggregatorV2V3Interface aggregator);\n\n function getPhaseRange(\n address base,\n address quote,\n uint16 phaseId\n ) external view returns (uint80 startingRoundId, uint80 endingRoundId);\n\n function getPreviousRoundId(\n address base,\n address quote,\n uint80 roundId\n ) external view returns (uint80 previousRoundId);\n\n function getNextRoundId(\n address base,\n address quote,\n uint80 roundId\n ) external view returns (uint80 nextRoundId);\n\n // Feed management\n\n function proposeFeed(\n address base,\n address quote,\n address aggregator\n ) external;\n\n function confirmFeed(\n address base,\n address quote,\n address aggregator\n ) external;\n\n // Proposed aggregator\n\n function getProposedFeed(address base, address quote)\n external\n view\n returns (AggregatorV2V3Interface proposedAggregator);\n\n function proposedGetRoundData(\n address base,\n address quote,\n uint80 roundId\n )\n external\n view\n returns (\n uint80 id,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function proposedLatestRoundData(address base, address quote)\n external\n view\n returns (\n uint80 id,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n // Phases\n function getCurrentPhaseId(address base, address quote) external view returns (uint16 currentPhaseId);\n}\n" + }, + "@equilibria/emptyset-batcher/batcher/Batcher.sol": { + "content": "//SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"@equilibria/root/control/unstructured/UOwnable.sol\";\nimport \"../interfaces/IBatcher.sol\";\nimport \"../interfaces/IEmptySetReserve.sol\";\n\nabstract contract Batcher is IBatcher, UOwnable {\n /// @dev Reserve address\n IEmptySetReserve public immutable RESERVE; // solhint-disable-line var-name-mixedcase\n\n /// @dev DSU address\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n\n /// @dev USDC address\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n /**\n * @notice Initializes the Batcher\n * @dev Called at implementation instantiate and constant for that implementation.\n * @param reserve EmptySet Reserve Aaddress\n * @param dsu DSU Token address\n * @param usdc USDC Token Address\n */\n constructor(IEmptySetReserve reserve, Token18 dsu, Token6 usdc) {\n RESERVE = reserve;\n DSU = dsu;\n USDC = usdc;\n\n DSU.approve(address(RESERVE));\n USDC.approve(address(RESERVE));\n\n __UOwnable__initialize();\n }\n\n /**\n * @notice Total USDC and DSU balance of the Batcher\n * @return Balance of DSU + balance of USDC\n */\n function totalBalance() public view returns (UFixed18) {\n return DSU.balanceOf().add(USDC.balanceOf());\n }\n\n /**\n * @notice Wraps `amount` of USDC, returned DSU to `to`\n * @param amount Amount of USDC to wrap\n * @param to Receiving address of resulting DSU\n */\n function wrap(UFixed18 amount, address to) external {\n _wrap(amount, to);\n emit Wrap(to, amount);\n }\n\n /**\n * @notice Pulls USDC from the `msg.sender` and pushes DSU to `to`\n * @dev Rounds USDC amount up if `amount` exceeds USDC decimal precision. Overrideable by implementation\n * @param amount Amount of USDC to pull\n * @param to Receiving address of resulting DSU\n */\n function _wrap(UFixed18 amount, address to) virtual internal {\n USDC.pull(msg.sender, amount, true);\n DSU.push(to, amount);\n }\n\n /**\n * @notice Unwraps `amount` of DSU, returned USDC to `to`\n * @param amount Amount of DSU to unwrap\n * @param to Receiving address of resulting USDC\n */\n function unwrap(UFixed18 amount, address to) external {\n _unwrap(amount, to);\n emit Unwrap(to, amount);\n }\n\n /**\n * @notice Pulls DSU from the `msg.sender` and pushes USDC to `to`\n * @dev Rounds USDC amount down if `amount` exceeds USDC decimal precision. Overrideable by implementation\n * @param amount Amount of DSU to pull\n * @param to Receiving address of resulting USDC\n */\n function _unwrap(UFixed18 amount, address to) virtual internal {\n DSU.pull(msg.sender, amount);\n USDC.push(to, amount);\n }\n\n /**\n * @notice Rebalances the USDC and DSU in the Batcher to maintain target balances\n * @dev Reverts if the new total balance is less than before\n */\n function rebalance() public {\n (UFixed18 usdcBalance, UFixed18 dsuBalance) = (USDC.balanceOf(), DSU.balanceOf());\n\n _rebalance(usdcBalance, dsuBalance);\n\n UFixed18 newDsuBalance = DSU.balanceOf();\n (UFixed18 oldBalance, UFixed18 newBalance) = (usdcBalance.add(dsuBalance), totalBalance());\n if (oldBalance.gt(newBalance)) revert BatcherBalanceMismatchError(oldBalance, newBalance);\n\n emit Rebalance(\n newDsuBalance.gt(dsuBalance) ? newDsuBalance.sub(dsuBalance) : UFixed18Lib.ZERO,\n dsuBalance.gt(newDsuBalance) ? dsuBalance.sub(newDsuBalance) : UFixed18Lib.ZERO\n );\n }\n\n /// @dev Hook for implementation for custom rebalance logic\n function _rebalance(UFixed18 usdcBalance, UFixed18 dsuBalance) virtual internal;\n\n /**\n * @notice Closes the Batcher. Repaying debt to Reserve and returning excess USDC to owner.\n */\n function close() external onlyOwner {\n _close();\n\n UFixed18 dsuBalance = DSU.balanceOf();\n UFixed18 repayAmount = UFixed18Lib.min(RESERVE.debt(address(this)), dsuBalance);\n UFixed18 returnAmount = dsuBalance.sub(repayAmount);\n\n RESERVE.repay(address(this), repayAmount);\n\n // If there is any excess DSU, redeem it for USDC and send to the owner\n if (!returnAmount.isZero()) {\n RESERVE.redeem(returnAmount);\n USDC.push(owner(), returnAmount);\n }\n\n emit Close(dsuBalance);\n }\n\n /// @dev Hook for implementation for custom close logic\n function _close() virtual internal;\n}\n" + }, + "@equilibria/emptyset-batcher/interfaces/IBatcher.sol": { + "content": "//SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"../interfaces/IEmptySetReserve.sol\";\n\ninterface IBatcher {\n event Wrap(address indexed to, UFixed18 amount);\n event Unwrap(address indexed to, UFixed18 amount);\n event Rebalance(UFixed18 newMinted, UFixed18 newRedeemed);\n event Close(UFixed18 amount);\n\n error BatcherNotImplementedError();\n error BatcherBalanceMismatchError(UFixed18 oldBalance, UFixed18 newBalance);\n\n function RESERVE() external view returns (IEmptySetReserve); // solhint-disable-line func-name-mixedcase\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\n function totalBalance() external view returns (UFixed18);\n function wrap(UFixed18 amount, address to) external;\n function unwrap(UFixed18 amount, address to) external;\n function rebalance() external;\n}\n" + }, + "@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol": { + "content": "//SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\n\ninterface IEmptySetReserve {\n event Redeem(address indexed account, uint256 costAmount, uint256 redeemAmount);\n event Mint(address indexed account, uint256 mintAmount, uint256 costAmount);\n event Repay(address indexed account, uint256 repayAmount);\n\n function debt(address borrower) external view returns (UFixed18);\n function repay(address borrower, UFixed18 amount) external;\n function mint(UFixed18 amount) external;\n function redeem(UFixed18 amount) external;\n}\n" + }, + "@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport \"./interfaces/IOracleProvider.sol\";\nimport \"./types/ChainlinkRegistry.sol\";\n\n/**\n * @title ChainlinkOracle\n * @notice Chainlink implementation of the IOracle interface.\n * @dev One instance per Chainlink price feed should be deployed. Multiple products may use the same\n * ChainlinkOracle instance if their payoff functions are based on the same underlying oracle.\n * This implementation only support non-negative prices.\n */\ncontract ChainlinkOracle is IOracleProvider {\n /// @dev Chainlink registry feed address\n ChainlinkRegistry public immutable registry;\n\n /// @dev Base token address for the Chainlink oracle\n address public immutable base;\n\n /// @dev Quote token address for the Chainlink oracle\n address public immutable quote;\n\n /// @dev Decimal offset used to normalize chainlink price to 18 decimals\n int256 private immutable _decimalOffset;\n\n /// @dev Mapping of the starting data for each underlying phase\n Phase[] private _phases;\n\n struct Phase {\n uint128 startingVersion;\n uint128 startingRoundId;\n }\n\n /**\n * @notice Initializes the contract state\n * @param registry_ Chainlink price feed registry\n * @param base_ base currency for feed\n * @param quote_ quote currency for feed\n */\n constructor(ChainlinkRegistry registry_, address base_, address quote_) {\n registry = registry_;\n base = base_;\n quote = quote_;\n\n // phaseId is 1-indexed, skip index 0\n _phases.push(Phase(uint128(0), uint128(0)));\n // phaseId is 1-indexed, first phase starts as version 0\n _phases.push(Phase(uint128(0), uint128(registry_.getStartingRoundId(base_, quote_, 1))));\n\n _decimalOffset = SafeCast.toInt256(10 ** registry_.decimals(base, quote));\n }\n\n /**\n * @notice Checks for a new price and updates the internal phase annotation state accordingly\n * @return The current oracle version after sync\n */\n function sync() external returns (OracleVersion memory) {\n // Fetch latest round\n ChainlinkRound memory round = registry.getLatestRound(base, quote);\n\n // Revert if the round id is 0\n if (uint64(round.roundId) == 0) revert InvalidOracleRound();\n\n // Update phase annotation when new phase detected\n while (round.phaseId() > _latestPhaseId()) {\n _phases.push(\n Phase(\n uint128(registry.getRoundCount(base, quote, _latestPhaseId())) +\n _phases[_phases.length - 1].startingVersion,\n uint128(registry.getStartingRoundId(base, quote, _latestPhaseId() + 1))\n )\n );\n }\n\n // Return packaged oracle version\n return _buildOracleVersion(round);\n }\n\n /**\n * @notice Returns the current oracle version\n * @return oracleVersion Current oracle version\n */\n function currentVersion() public view returns (OracleVersion memory oracleVersion) {\n return _buildOracleVersion(registry.getLatestRound(base, quote));\n }\n\n /**\n * @notice Returns the current oracle version\n * @param version The version of which to lookup\n * @return oracleVersion Oracle version at version `version`\n */\n function atVersion(uint256 version) public view returns (OracleVersion memory oracleVersion) {\n return _buildOracleVersion(registry.getRound(base, quote, _versionToRoundId(version)), version);\n }\n\n /**\n * @notice Builds an oracle version object from a Chainlink round object\n * @dev Computes the version for the round\n * @param round Chainlink round to build from\n * @return Built oracle version\n */\n function _buildOracleVersion(ChainlinkRound memory round) private view returns (OracleVersion memory) {\n Phase memory phase = _phases[round.phaseId()];\n uint256 version = uint256(phase.startingVersion) + round.roundId - uint256(phase.startingRoundId);\n return _buildOracleVersion(round, version);\n }\n\n /**\n * @notice Builds an oracle version object from a Chainlink round object\n * @param round Chainlink round to build from\n * @param version Determined version for the round\n * @return Built oracle version\n */\n function _buildOracleVersion(ChainlinkRound memory round, uint256 version)\n private view returns (OracleVersion memory) {\n Fixed18 price = Fixed18Lib.ratio(round.answer, _decimalOffset);\n return OracleVersion({ version: version, timestamp: round.timestamp, price: price });\n }\n\n /**\n * @notice Computes the chainlink round ID from a version\n * @param version Version to compute from\n * @return Chainlink round ID\n */\n function _versionToRoundId(uint256 version) private view returns (uint256) {\n Phase memory phase = _versionToPhase(version);\n return uint256(phase.startingRoundId) + version - uint256(phase.startingVersion);\n }\n\n /**\n * @notice Computes the chainlink phase ID from a version\n * @param version Version to compute from\n * @return phase Chainlink phase\n */\n function _versionToPhase(uint256 version) private view returns (Phase memory phase) {\n uint256 phaseId = _latestPhaseId();\n phase = _phases[phaseId];\n while (uint256(phase.startingVersion) > version) {\n phaseId--;\n phase = _phases[phaseId];\n }\n }\n\n /**\n * @notice Returns the latest phase ID that this contract has seen via `sync()`\n * @return Latest seen phase ID\n */\n function _latestPhaseId() private view returns (uint16) {\n return uint16(_phases.length - 1);\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\n\ninterface IOracleProvider {\n /// @dev Error for invalid oracle round\n error InvalidOracleRound();\n\n /// @dev A singular oracle version with its corresponding data\n struct OracleVersion {\n /// @dev The iterative version\n uint256 version;\n\n /// @dev the timestamp of the oracle update\n uint256 timestamp;\n\n /// @dev The oracle price of the corresponding version\n Fixed18 price;\n }\n\n function sync() external returns (OracleVersion memory);\n function currentVersion() external view returns (OracleVersion memory);\n function atVersion(uint256 oracleVersion) external view returns (OracleVersion memory);\n}\n" + }, + "@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\nimport \"./interfaces/IOracleProvider.sol\";\n\n/**\n * @title ReservoirFeedOracle\n * @notice Reservoir implementation of the IOracle interface, using Reservoir's AggregatorV3Interface adaptors\n * @dev This is a naive implementation which pushes all validation to the underlying. No staleness checks are possible\n This oracle should not be used for regular Chainlink Data Feeds\n */\ncontract ReservoirFeedOracle is IOracleProvider {\n error InvalidOracleVersion();\n\n /// @dev Chainlink price feed to read from\n AggregatorV3Interface public immutable feed;\n\n /// @dev Decimal offset used to normalize chainlink price to 18 decimals\n int256 private immutable _decimalOffset;\n\n /// @dev Which underlying round to consider version 0: version = roundId - _versionOffset\n uint80 private immutable _versionOffset;\n\n /**\n * @notice Initializes the contract state\n * @param feed_ Reservoir price feed\n * @param versionOffset_ Version offset from source round ID\n */\n constructor(AggregatorV3Interface feed_, uint80 versionOffset_) {\n feed = feed_;\n _versionOffset = versionOffset_;\n _decimalOffset = SafeCast.toInt256(10 ** feed_.decimals());\n }\n\n /**\n * @notice Checks for a new price. Does not perform staleness validation as the underlying oracle does not\n support this.\n * @return The current oracle version after sync\n */\n function sync() external view returns (OracleVersion memory) {\n (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.latestRoundData();\n\n return _buildOracleVersion(roundId, feedPrice, timestamp);\n }\n\n /**\n * @notice Returns the current oracle version\n * @return oracleVersion Current oracle version\n */\n function currentVersion() public view returns (OracleVersion memory oracleVersion) {\n (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.latestRoundData();\n\n return _buildOracleVersion(roundId, feedPrice, timestamp);\n }\n\n /**\n * @notice Returns the oracle version specified\n * @dev Converts the passed in version to a roundID by adding _versionOffset\n * @param version The version of which to lookup\n * @return oracleVersion Oracle version at version `version`\n */\n function atVersion(uint256 version) public view returns (OracleVersion memory oracleVersion) {\n // To convert from version to roundId, we add the versionOffset\n uint256 feedRoundID = version + _versionOffset;\n if (feedRoundID > type(uint80).max) revert InvalidOracleVersion();\n (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.getRoundData(uint80(feedRoundID));\n\n return _buildOracleVersion(roundId, feedPrice, timestamp);\n }\n\n /**\n * @notice Builds an oracle version object from a Chainlink round object\n * @dev Converts the passed in roundID to a version by subtracting _versionOffset\n * @param roundId ReservoirRoundId round to build from\n * @param feedPrice price returns by the oracle\n * @param timestamp round timestamps\n * @return Built oracle version\n */\n function _buildOracleVersion(uint80 roundId, int256 feedPrice, uint256 timestamp)\n private view returns (OracleVersion memory) {\n Fixed18 price = Fixed18Lib.ratio(feedPrice, _decimalOffset);\n\n // To convert from roundId to version, we subtract the versionOffset\n return OracleVersion({ version: roundId - _versionOffset, timestamp: timestamp, price: price });\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol\";\n\ncontract PassthroughChainlinkFeed {\n FeedRegistryInterface private _underlying;\n\n constructor(FeedRegistryInterface underlying_) {\n _underlying = underlying_;\n }\n\n function decimals(address base, address quote) external view returns (uint8) {\n return _underlying.decimals(base, quote);\n }\n\n function getRoundData(address base, address quote, uint80 roundId) external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.getRoundData(base, quote, roundId);\n }\n\n function getPhaseRange(address base, address quote, uint16 phaseId) external view returns (uint80, uint80) {\n return _underlying.getPhaseRange(base, quote, phaseId);\n }\n\n function latestRoundData(address base, address quote) external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.latestRoundData(base, quote);\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\ncontract PassthroughDataFeed {\n AggregatorV3Interface private _underlying;\n\n constructor(AggregatorV3Interface underlying_) {\n _underlying = underlying_;\n }\n\n function decimals() external view returns (uint8) {\n return _underlying.decimals();\n }\n\n function getRoundData(uint80 roundId) external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.getRoundData(roundId);\n }\n\n function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) {\n return _underlying.latestRoundData();\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\ncontract TestnetChainlinkFeedRegistry {\n mapping(address => mapping(address => uint8)) public decimals;\n\n function registerFeed(address base, address quote, uint8 newDecimals) external {\n decimals[base][quote] = newDecimals;\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/types/ChainlinkRegistry.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol\";\nimport \"./ChainlinkRound.sol\";\n\n/// @dev ChainlinkRegistry type\ntype ChainlinkRegistry is address;\nusing ChainlinkRegistryLib for ChainlinkRegistry global;\n\n/**\n * @title ChainlinkRegistryLib\n * @notice Library that manages interfacing with the Chainlink Feed Registry.\n */\nlibrary ChainlinkRegistryLib {\n /**\n * @notice Returns the decimal amount for a specific feed\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @return Decimal amount\n */\n function decimals(ChainlinkRegistry self, address base, address quote) internal view returns (uint8) {\n return FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).decimals(base, quote);\n }\n\n /**\n * @notice Returns the latest round data for a specific feed\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @return Latest round data\n */\n function getLatestRound(ChainlinkRegistry self, address base, address quote) internal view returns (ChainlinkRound memory) {\n (uint80 roundId, int256 answer, , uint256 updatedAt, ) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).latestRoundData(base, quote);\n return ChainlinkRound({roundId: roundId, timestamp: updatedAt, answer: answer});\n }\n\n /**\n * @notice Returns a specific round's data for a specific feed\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @param roundId The specific round to fetch data for\n * @return Specific round's data\n */\n function getRound(ChainlinkRegistry self, address base, address quote, uint256 roundId) internal view returns (ChainlinkRound memory) {\n (, int256 answer, , uint256 updatedAt, ) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).getRoundData(base, quote, uint80(roundId));\n return ChainlinkRound({roundId: roundId, timestamp: updatedAt, answer: answer});\n }\n\n\n /**\n * @notice Returns the first round ID for a specific phase ID\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @param phaseId The specific phase to fetch data for\n * @return startingRoundId The starting round ID for the phase\n */\n function getStartingRoundId(ChainlinkRegistry self, address base, address quote, uint16 phaseId)\n internal view returns (uint80 startingRoundId) {\n (startingRoundId, ) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).getPhaseRange(base, quote, phaseId);\n }\n\n /**\n * @notice Returns the quantity of rounds for a specific phase ID\n * @param self Chainlink Feed Registry to operate on\n * @param base Base currency token address\n * @param quote Quote currency token address\n * @param phaseId The specific phase to fetch data for\n * @return The quantity of rounds for the phase\n */\n function getRoundCount(ChainlinkRegistry self, address base, address quote, uint256 phaseId)\n internal view returns (uint256) {\n (uint80 startingRoundId, uint80 endingRoundId) =\n FeedRegistryInterface(ChainlinkRegistry.unwrap(self)).getPhaseRange(base, quote, uint16(phaseId));\n\n // If the phase has a starting and ending roundId of 0, then there are no rounds.\n // Convert phase rounds to aggregator rounds to check ID\n if (uint64(startingRoundId) == 0 && uint64(endingRoundId) == 0) return 0;\n return uint256(endingRoundId - startingRoundId + 1);\n }\n}\n" + }, + "@equilibria/perennial-oracle/contracts/types/ChainlinkRound.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.15;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @dev ChainlinkRound type\nstruct ChainlinkRound {\n uint256 timestamp;\n int256 answer;\n uint256 roundId;\n}\nusing ChainlinkRoundLib for ChainlinkRound global;\n\n/**\n * @title ChainlinkRoundLib\n * @notice Library that manages Chainlink round parsing.\n */\nlibrary ChainlinkRoundLib {\n /// @dev Phase ID offset location in the round ID\n uint256 constant private PHASE_OFFSET = 64;\n\n /**\n * @notice Computes the chainlink phase ID from a round\n * @param self Round to compute from\n * @return Chainlink phase ID\n */\n function phaseId(ChainlinkRound memory self) internal pure returns (uint16) {\n return uint16(self.roundId >> PHASE_OFFSET);\n }\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwnable/UCrossChainOwnable_Arbitrum.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol\";\nimport \"./UCrossChainOwnable.sol\";\n\n/**\n * @title UCrossChainOwnable_Arbitrum\n * @notice Library to manage the cross-chain ownership lifecycle of Arbitrum upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance. This contract\n * is specific to the Arbitrum L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwnable} for initialization and update usage.\n */\nabstract contract UCrossChainOwnable_Arbitrum is CrossChainEnabledArbitrumL2, UCrossChainOwnable {\n constructor() CrossChainEnabledArbitrumL2() {}\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwnable/UCrossChainOwnable_Optimism.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol\";\nimport \"./UCrossChainOwnable.sol\";\n\n/**\n * @title UCrossChainOwnable_Optimism\n * @notice Library to manage the cross-chain ownership lifecycle of upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance. This contract\n * is specific to the Optimism L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwnable} for initialization and update usage.\n */\nabstract contract UCrossChainOwnable_Optimism is CrossChainEnabledOptimism, UCrossChainOwnable {\n /// @dev System address for the CrossDomainMessenger. This address is ONLY valid on the L2 side\n address public constant L2_CROSS_DOMAIN_MESSENGER_ADDRESS = address(0x4200000000000000000000000000000000000007);\n\n constructor() CrossChainEnabledOptimism(L2_CROSS_DOMAIN_MESSENGER_ADDRESS) {}\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwnable/UCrossChainOwnable.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/crosschain/CrossChainEnabled.sol\";\nimport \"../UOwnable.sol\";\nimport \"../../../storage/UStorage.sol\";\n\n/**\n * @title UCrossChainOwnable\n * @notice Library to manage the cross-chain ownership lifecycle of upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance.\n *\n * Upon initialization, the `owner` will be set to the `msg.sender` of the initialize method.\n * Ownership should then be transferred to the cross-chain owner via the `updatePendingOwner`\n * and `acceptedPending` owner methods. Upon accepting ownership via the cross-chain address,\n * a fuse will be tripped, preventing same-chain ownership going forward.\n */\nabstract contract UCrossChainOwnable is UOwnable, CrossChainEnabled {\n BoolStorage private constant _crossChainRestricted = BoolStorage.wrap(keccak256(\"equilibria.root.UCrossChainOwnable.crossChainRestricted\"));\n function crossChainRestricted() public view returns (bool) { return _crossChainRestricted.read(); }\n\n function _beforeAcceptOwner() internal override {\n if (!crossChainRestricted()) _crossChainRestricted.store(true);\n }\n\n function _sender() internal view override returns (address) {\n if (crossChainRestricted()) return _crossChainSender();\n return msg.sender;\n }\n}\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Arbitrum.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../CrossChainOwnable/UCrossChainOwnable_Arbitrum.sol\";\nimport \"./UCrossChainOwner.sol\";\n\n/**\n * @title UCrossChainOwner_Arbitrum\n * @notice Contract to act as an owner of other contracts\n * @dev This contract is designed to act as an owner of any Ownable contract, allowing\n * Cross Chain Ownership without modification to the underlying ownable contract. This contract\n * is specific to the Arbitrum L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwner} for initialization and usage.\n */\ncontract UCrossChainOwner_Arbitrum is UCrossChainOwner, UCrossChainOwnable_Arbitrum { }\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Optimism.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../CrossChainOwnable/UCrossChainOwnable_Optimism.sol\";\nimport \"./UCrossChainOwner.sol\";\n\n/**\n * @title UCrossChainOwner_Arbitrum\n * @notice Contract to act as an owner of other contracts\n * @dev This contract is designed to act as an owner of any Ownable contract, allowing\n * Cross Chain Ownership without modification to the underlying ownable contract. This contract\n * is specific to the Optimism L2-side and should not be used on other chains.\n *\n * See {UCrossChainOwner} for initialization and usage.\n */\ncontract UCrossChainOwner_Optimism is UCrossChainOwner, UCrossChainOwnable_Optimism { }\n" + }, + "@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../CrossChainOwnable/UCrossChainOwnable.sol\";\n\n/**\n * @title UCrossChainOwner\n * @notice Contract to act as an owner of other contracts\n * @dev This contract is designed to act as an owner of any Ownable contract, allowing\n * Cross Chain Ownership without modification to the underlying ownable contract\n */\nabstract contract UCrossChainOwner is UCrossChainOwnable {\n function initialize() external initializer(1) {\n super.__UOwnable__initialize();\n }\n\n function execute(\n address payable to,\n bytes memory data,\n uint256 value\n ) payable external onlyOwner returns (bytes memory ret) {\n if (data.length == 0) {\n Address.sendValue(to, value);\n } else {\n ret = Address.functionCallWithValue(to, data, value);\n }\n }\n}\n" + }, + "@equilibria/root/control/unstructured/UInitializable.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../../storage/UStorage.sol\";\n\n/**\n * @title UInitializable\n * @notice Library to manage the initialization lifecycle of upgradeable contracts\n * @dev `UInitializable` allows the creation of pseudo-constructors for upgradeable contracts. One\n * `initializer` should be declared per top-level contract. Child contracts can use the `onlyInitializer`\n * modifier to tag their internal initialization functions to ensure that they can only be called\n * from a top-level `initializer` or a constructor.\n */\nabstract contract UInitializable {\n error UInitializableZeroVersionError();\n error UInitializableAlreadyInitializedError(uint256 version);\n error UInitializableNotInitializingError();\n\n event Initialized(uint256 version);\n\n /// @dev The initialized flag\n Uint256Storage private constant _version = Uint256Storage.wrap(keccak256(\"equilibria.root.UInitializable.version\"));\n\n /// @dev The initializing flag\n BoolStorage private constant _initializing = BoolStorage.wrap(keccak256(\"equilibria.root.UInitializable.initializing\"));\n\n /// @dev Can only be called once per version, `version` is 1-indexed\n modifier initializer(uint256 version) {\n if (version == 0) revert UInitializableZeroVersionError();\n if (_version.read() >= version) revert UInitializableAlreadyInitializedError(version);\n\n _version.store(version);\n _initializing.store(true);\n\n _;\n\n _initializing.store(false);\n emit Initialized(version);\n }\n\n /// @dev Can only be called from an initializer or constructor\n modifier onlyInitializer() {\n if (!_constructing() && !_initializing.read()) revert UInitializableNotInitializingError();\n _;\n }\n\n /**\n * @notice Returns whether the contract is currently being constructed\n * @dev {Address.isContract} returns false for contracts currently in the process of being constructed\n * @return Whether the contract is currently being constructed\n */\n function _constructing() private view returns (bool) {\n return !Address.isContract(address(this));\n }\n}\n" + }, + "@equilibria/root/control/unstructured/UOwnable.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./UInitializable.sol\";\nimport \"../../storage/UStorage.sol\";\n\n/**\n * @title UOwnable\n * @notice Library to manage the ownership lifecycle of upgradeable contracts.\n * @dev This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance.\n */\nabstract contract UOwnable is UInitializable {\n event OwnerUpdated(address indexed newOwner);\n event PendingOwnerUpdated(address indexed newPendingOwner);\n\n error UOwnableNotOwnerError(address sender);\n error UOwnableNotPendingOwnerError(address sender);\n\n /// @dev The owner address\n AddressStorage private constant _owner = AddressStorage.wrap(keccak256(\"equilibria.root.UOwnable.owner\"));\n function owner() public view returns (address) { return _owner.read(); }\n\n /// @dev The pending owner address\n AddressStorage private constant _pendingOwner = AddressStorage.wrap(keccak256(\"equilibria.root.UOwnable.pendingOwner\"));\n function pendingOwner() public view returns (address) { return _pendingOwner.read(); }\n\n /**\n * @notice Initializes the contract setting `msg.sender` as the initial owner\n */\n function __UOwnable__initialize() internal onlyInitializer {\n _updateOwner(_sender());\n }\n\n /**\n * @notice Updates the new pending owner\n * @dev Can only be called by the current owner\n * New owner does not take affect until that address calls `acceptOwner()`\n * @param newPendingOwner New pending owner address\n */\n function updatePendingOwner(address newPendingOwner) public onlyOwner {\n _pendingOwner.store(newPendingOwner);\n emit PendingOwnerUpdated(newPendingOwner);\n }\n\n /**\n * @notice Accepts and transfers the ownership of the contract to the pending owner\n * @dev Can only be called by the pending owner to ensure correctness. Calls to the `_beforeAcceptOwner` hook\n * to perform logic before updating ownership.\n */\n function acceptOwner() public {\n _beforeAcceptOwner();\n\n if (_sender() != pendingOwner()) revert UOwnableNotPendingOwnerError(_sender());\n\n _updateOwner(pendingOwner());\n updatePendingOwner(address(0));\n }\n\n\n /// @dev Hook for inheriting contracts to perform logic before accepting ownership\n function _beforeAcceptOwner() internal virtual {}\n\n /**\n * @notice Updates the owner address\n * @param newOwner New owner address\n */\n function _updateOwner(address newOwner) private {\n _owner.store(newOwner);\n emit OwnerUpdated(newOwner);\n }\n\n function _sender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n /// @dev Throws if called by any account other than the owner\n modifier onlyOwner {\n if (owner() != _sender()) revert UOwnableNotOwnerError(_sender());\n _;\n }\n}\n" + }, + "@equilibria/root/control/unstructured/UReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./UInitializable.sol\";\nimport \"../../storage/UStorage.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n *\n * NOTE: This contract has been extended from the Open Zeppelin library to include an\n * unstructured storage pattern, so that it can be safely mixed in with upgradeable\n * contracts without affecting their storage patterns through inheritance.\n */\nabstract contract UReentrancyGuard is UInitializable {\n error UReentrancyGuardReentrantCallError();\n\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n /**\n * @dev unstructured storage slot for the reentrancy status\n */\n Uint256Storage private constant _status = Uint256Storage.wrap(keccak256(\"equilibria.root.UReentrancyGuard.status\"));\n\n /**\n * @dev Initializes the contract setting the status to _NOT_ENTERED.\n */\n function __UReentrancyGuard__initialize() internal onlyInitializer {\n _status.store(_NOT_ENTERED);\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n if (_status.read() == _ENTERED) revert UReentrancyGuardReentrantCallError();\n\n // Any calls to nonReentrant after this point will fail\n _status.store(_ENTERED);\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status.store(_NOT_ENTERED);\n }\n}\n" + }, + "@equilibria/root/curve/CurveMath.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../number/types/UFixed18.sol\";\nimport \"../number/types/Fixed18.sol\";\n\n/**\n * @title CurveMath\n * @notice Library for managing math operations for utilization curves.\n */\nlibrary CurveMath {\n error CurveMathOutOfBoundsError();\n\n /**\n * @notice Computes a linear interpolation between two points\n * @param startX First point's x-coordinate\n * @param startY First point's y-coordinate\n * @param endX Second point's x-coordinate\n * @param endY Second point's y-coordinate\n * @param targetX x-coordinate to interpolate\n * @return y-coordinate for `targetX` along the line from (`startX`, `startY`) -> (`endX`, `endY`)\n */\n function linearInterpolation(\n UFixed18 startX,\n Fixed18 startY,\n UFixed18 endX,\n Fixed18 endY,\n UFixed18 targetX\n ) internal pure returns (Fixed18) {\n if (targetX.lt(startX) || targetX.gt(endX)) revert CurveMathOutOfBoundsError();\n\n UFixed18 xRange = endX.sub(startX);\n Fixed18 yRange = endY.sub(startY);\n UFixed18 xRatio = targetX.sub(startX).div(xRange);\n return yRange.mul(Fixed18Lib.from(xRatio)).add(startY);\n }\n}\n" + }, + "@equilibria/root/curve/types/JumpRateUtilizationCurve.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../CurveMath.sol\";\nimport \"../../number/types/PackedUFixed18.sol\";\nimport \"../../number/types/PackedFixed18.sol\";\n\n/// @dev JumpRateUtilizationCurve type\nstruct JumpRateUtilizationCurve {\n PackedFixed18 minRate;\n PackedFixed18 maxRate;\n PackedFixed18 targetRate;\n PackedUFixed18 targetUtilization;\n}\nusing JumpRateUtilizationCurveLib for JumpRateUtilizationCurve global;\ntype JumpRateUtilizationCurveStorage is bytes32;\nusing JumpRateUtilizationCurveStorageLib for JumpRateUtilizationCurveStorage global;\n\n/**\n * @title JumpRateUtilizationCurveLib\n * @notice Library for the Jump Rate utilization curve type\n */\nlibrary JumpRateUtilizationCurveLib {\n /**\n * @notice Computes the corresponding rate for a utilization ratio\n * @param utilization The utilization ratio\n * @return The corresponding rate\n */\n function compute(JumpRateUtilizationCurve memory self, UFixed18 utilization) internal pure returns (Fixed18) {\n UFixed18 targetUtilization = self.targetUtilization.unpack();\n if (utilization.lt(targetUtilization)) {\n return CurveMath.linearInterpolation(\n UFixed18Lib.ZERO,\n self.minRate.unpack(),\n targetUtilization,\n self.targetRate.unpack(),\n utilization\n );\n }\n if (utilization.lt(UFixed18Lib.ONE)) {\n return CurveMath.linearInterpolation(\n targetUtilization,\n self.targetRate.unpack(),\n UFixed18Lib.ONE,\n self.maxRate.unpack(),\n utilization\n );\n }\n return self.maxRate.unpack();\n }\n}\n\nlibrary JumpRateUtilizationCurveStorageLib {\n function read(JumpRateUtilizationCurveStorage self) internal view returns (JumpRateUtilizationCurve memory) {\n return _storagePointer(self);\n }\n\n function store(JumpRateUtilizationCurveStorage self, JumpRateUtilizationCurve memory value) internal {\n JumpRateUtilizationCurve storage storagePointer = _storagePointer(self);\n\n storagePointer.minRate = value.minRate;\n storagePointer.maxRate = value.maxRate;\n storagePointer.targetRate = value.targetRate;\n storagePointer.targetUtilization = value.targetUtilization;\n }\n\n function _storagePointer(JumpRateUtilizationCurveStorage self)\n private pure returns (JumpRateUtilizationCurve storage pointer) {\n assembly { pointer.slot := self }\n }\n}" + }, + "@equilibria/root/number/types/Fixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport \"./UFixed18.sol\";\nimport \"./PackedFixed18.sol\";\n\n/// @dev Fixed18 type\ntype Fixed18 is int256;\nusing Fixed18Lib for Fixed18 global;\ntype Fixed18Storage is bytes32;\nusing Fixed18StorageLib for Fixed18Storage global;\n\n/**\n * @title Fixed18Lib\n * @notice Library for the signed fixed-decimal type.\n */\nlibrary Fixed18Lib {\n error Fixed18OverflowError(uint256 value);\n error Fixed18PackingOverflowError(int256 value);\n error Fixed18PackingUnderflowError(int256 value);\n\n int256 private constant BASE = 1e18;\n Fixed18 public constant ZERO = Fixed18.wrap(0);\n Fixed18 public constant ONE = Fixed18.wrap(BASE);\n Fixed18 public constant NEG_ONE = Fixed18.wrap(-1 * BASE);\n Fixed18 public constant MAX = Fixed18.wrap(type(int256).max);\n Fixed18 public constant MIN = Fixed18.wrap(type(int256).min);\n\n /**\n * @notice Creates a signed fixed-decimal from an unsigned fixed-decimal\n * @param a Unsigned fixed-decimal\n * @return New signed fixed-decimal\n */\n function from(UFixed18 a) internal pure returns (Fixed18) {\n uint256 value = UFixed18.unwrap(a);\n if (value > uint256(type(int256).max)) revert Fixed18OverflowError(value);\n return Fixed18.wrap(int256(value));\n }\n\n /**\n * @notice Creates a signed fixed-decimal from a sign and an unsigned fixed-decimal\n * @param s Sign\n * @param m Unsigned fixed-decimal magnitude\n * @return New signed fixed-decimal\n */\n function from(int256 s, UFixed18 m) internal pure returns (Fixed18) {\n if (s > 0) return from(m);\n if (s < 0) return Fixed18.wrap(-1 * Fixed18.unwrap(from(m)));\n return ZERO;\n }\n\n /**\n * @notice Creates a signed fixed-decimal from a signed integer\n * @param a Signed number\n * @return New signed fixed-decimal\n */\n function from(int256 a) internal pure returns (Fixed18) {\n return Fixed18.wrap(a * BASE);\n }\n\n /**\n * @notice Creates a packed signed fixed-decimal from an signed fixed-decimal\n * @param a signed fixed-decimal\n * @return New packed signed fixed-decimal\n */\n function pack(Fixed18 a) internal pure returns (PackedFixed18) {\n int256 value = Fixed18.unwrap(a);\n if (value > type(int128).max) revert Fixed18PackingOverflowError(value);\n if (value < type(int128).min) revert Fixed18PackingUnderflowError(value);\n return PackedFixed18.wrap(int128(value));\n }\n\n /**\n * @notice Returns whether the signed fixed-decimal is equal to zero.\n * @param a Signed fixed-decimal\n * @return Whether the signed fixed-decimal is zero.\n */\n function isZero(Fixed18 a) internal pure returns (bool) {\n return Fixed18.unwrap(a) == 0;\n }\n\n /**\n * @notice Adds two signed fixed-decimals `a` and `b` together\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Resulting summed signed fixed-decimal\n */\n function add(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) + Fixed18.unwrap(b));\n }\n\n /**\n * @notice Subtracts signed fixed-decimal `b` from `a`\n * @param a Signed fixed-decimal to subtract from\n * @param b Signed fixed-decimal to subtract\n * @return Resulting subtracted signed fixed-decimal\n */\n function sub(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) - Fixed18.unwrap(b));\n }\n\n /**\n * @notice Multiplies two signed fixed-decimals `a` and `b` together\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Resulting multiplied signed fixed-decimal\n */\n function mul(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / BASE);\n }\n\n /**\n * @notice Divides signed fixed-decimal `a` by `b`\n * @param a Signed fixed-decimal to divide\n * @param b Signed fixed-decimal to divide by\n * @return Resulting divided signed fixed-decimal\n */\n function div(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) * BASE / Fixed18.unwrap(b));\n }\n\n /**\n * @notice Divides unsigned fixed-decimal `a` by `b`\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0`, `MAX` for `n/0`, and `MIN` for `-n/0`.\n * @param a Unsigned fixed-decimal to divide\n * @param b Unsigned fixed-decimal to divide by\n * @return Resulting divided unsigned fixed-decimal\n */\n function unsafeDiv(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n if (isZero(b)) {\n if (gt(a, ZERO)) return MAX;\n if (lt(a, ZERO)) return MIN;\n return ONE;\n } else {\n return div(a, b);\n }\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First signed fixed-decimal\n * @param b Signed number to multiply by\n * @param c Signed number to divide by\n * @return Resulting computation\n */\n function muldiv(Fixed18 a, int256 b, int256 c) internal pure returns (Fixed18) {\n return muldiv(a, Fixed18.wrap(b), Fixed18.wrap(c));\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First signed fixed-decimal\n * @param b Signed fixed-decimal to multiply by\n * @param c Signed fixed-decimal to divide by\n * @return Resulting computation\n */\n function muldiv(Fixed18 a, Fixed18 b, Fixed18 c) internal pure returns (Fixed18) {\n return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / Fixed18.unwrap(c));\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is equal to `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is equal to `b`\n */\n function eq(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return compare(a, b) == 1;\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is greater than `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is greater than `b`\n */\n function gt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return compare(a, b) == 2;\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is less than `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is less than `b`\n */\n function lt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return compare(a, b) == 0;\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is greater than or equal to `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is greater than or equal to `b`\n */\n function gte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return gt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Returns whether signed fixed-decimal `a` is less than or equal to `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Whether `a` is less than or equal to `b`\n */\n function lte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\n return lt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Compares the signed fixed-decimals `a` and `b`\n * @dev Returns: 2 for greater than\n * 1 for equal to\n * 0 for less than\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Compare result of `a` and `b`\n */\n function compare(Fixed18 a, Fixed18 b) internal pure returns (uint256) {\n (int256 au, int256 bu) = (Fixed18.unwrap(a), Fixed18.unwrap(b));\n if (au > bu) return 2;\n if (au < bu) return 0;\n return 1;\n }\n\n /**\n * @notice Returns a signed fixed-decimal representing the ratio of `a` over `b`\n * @param a First signed number\n * @param b Second signed number\n * @return Ratio of `a` over `b`\n */\n function ratio(int256 a, int256 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(a * BASE / b);\n }\n\n /**\n * @notice Returns the minimum of signed fixed-decimals `a` and `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Minimum of `a` and `b`\n */\n function min(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(SignedMath.min(Fixed18.unwrap(a), Fixed18.unwrap(b)));\n }\n\n /**\n * @notice Returns the maximum of signed fixed-decimals `a` and `b`\n * @param a First signed fixed-decimal\n * @param b Second signed fixed-decimal\n * @return Maximum of `a` and `b`\n */\n function max(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\n return Fixed18.wrap(SignedMath.max(Fixed18.unwrap(a), Fixed18.unwrap(b)));\n }\n\n /**\n * @notice Converts the signed fixed-decimal into an integer, truncating any decimal portion\n * @param a Signed fixed-decimal\n * @return Truncated signed number\n */\n function truncate(Fixed18 a) internal pure returns (int256) {\n return Fixed18.unwrap(a) / BASE;\n }\n\n /**\n * @notice Returns the sign of the signed fixed-decimal\n * @dev Returns: -1 for negative\n * 0 for zero\n * 1 for positive\n * @param a Signed fixed-decimal\n * @return Sign of the signed fixed-decimal\n */\n function sign(Fixed18 a) internal pure returns (int256) {\n if (Fixed18.unwrap(a) > 0) return 1;\n if (Fixed18.unwrap(a) < 0) return -1;\n return 0;\n }\n\n /**\n * @notice Returns the absolute value of the signed fixed-decimal\n * @param a Signed fixed-decimal\n * @return Absolute value of the signed fixed-decimal\n */\n function abs(Fixed18 a) internal pure returns (UFixed18) {\n return UFixed18.wrap(SignedMath.abs(Fixed18.unwrap(a)));\n }\n}\n\nlibrary Fixed18StorageLib {\n function read(Fixed18Storage self) internal view returns (Fixed18 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(Fixed18Storage self, Fixed18 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/number/types/PackedFixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./Fixed18.sol\";\n\n/// @dev PackedFixed18 type\ntype PackedFixed18 is int128;\nusing PackedFixed18Lib for PackedFixed18 global;\n\n/**\n * @title PackedFixed18Lib\n * @dev A packed version of the Fixed18 which takes up half the storage space (two PackedFixed18 can be packed\n * into a single slot). Only valid within the range -1.7014118e+20 <= x <= 1.7014118e+20.\n * @notice Library for the packed signed fixed-decimal type.\n */\nlibrary PackedFixed18Lib {\n PackedFixed18 public constant MAX = PackedFixed18.wrap(type(int128).max);\n PackedFixed18 public constant MIN = PackedFixed18.wrap(type(int128).min);\n\n /**\n * @notice Creates an unpacked signed fixed-decimal from a packed signed fixed-decimal\n * @param self packed signed fixed-decimal\n * @return New unpacked signed fixed-decimal\n */\n function unpack(PackedFixed18 self) internal pure returns (Fixed18) {\n return Fixed18.wrap(int256(PackedFixed18.unwrap(self)));\n }\n}\n" + }, + "@equilibria/root/number/types/PackedUFixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./UFixed18.sol\";\n\n/// @dev PackedUFixed18 type\ntype PackedUFixed18 is uint128;\nusing PackedUFixed18Lib for PackedUFixed18 global;\n\n/**\n * @title PackedUFixed18Lib\n * @dev A packed version of the UFixed18 which takes up half the storage space (two PackedUFixed18 can be packed\n * into a single slot). Only valid within the range 0 <= x <= 3.4028237e+20.\n * @notice Library for the packed unsigned fixed-decimal type.\n */\nlibrary PackedUFixed18Lib {\n PackedUFixed18 public constant MAX = PackedUFixed18.wrap(type(uint128).max);\n\n /**\n * @notice Creates an unpacked unsigned fixed-decimal from a packed unsigned fixed-decimal\n * @param self packed unsigned fixed-decimal\n * @return New unpacked unsigned fixed-decimal\n */\n function unpack(PackedUFixed18 self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(PackedUFixed18.unwrap(self)));\n }\n}\n" + }, + "@equilibria/root/number/types/UFixed18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"./Fixed18.sol\";\nimport \"./PackedUFixed18.sol\";\n\n/// @dev UFixed18 type\ntype UFixed18 is uint256;\nusing UFixed18Lib for UFixed18 global;\ntype UFixed18Storage is bytes32;\nusing UFixed18StorageLib for UFixed18Storage global;\n\n/**\n * @title UFixed18Lib\n * @notice Library for the unsigned fixed-decimal type.\n */\nlibrary UFixed18Lib {\n error UFixed18UnderflowError(int256 value);\n error UFixed18PackingOverflowError(uint256 value);\n\n uint256 private constant BASE = 1e18;\n UFixed18 public constant ZERO = UFixed18.wrap(0);\n UFixed18 public constant ONE = UFixed18.wrap(BASE);\n UFixed18 public constant MAX = UFixed18.wrap(type(uint256).max);\n\n /**\n * @notice Creates a unsigned fixed-decimal from a signed fixed-decimal\n * @param a Signed fixed-decimal\n * @return New unsigned fixed-decimal\n */\n function from(Fixed18 a) internal pure returns (UFixed18) {\n int256 value = Fixed18.unwrap(a);\n if (value < 0) revert UFixed18UnderflowError(value);\n return UFixed18.wrap(uint256(value));\n }\n\n /**\n * @notice Creates a unsigned fixed-decimal from a unsigned integer\n * @param a Unsigned number\n * @return New unsigned fixed-decimal\n */\n function from(uint256 a) internal pure returns (UFixed18) {\n return UFixed18.wrap(a * BASE);\n }\n\n /**\n * @notice Creates a packed unsigned fixed-decimal from an unsigned fixed-decimal\n * @param a unsigned fixed-decimal\n * @return New packed unsigned fixed-decimal\n */\n function pack(UFixed18 a) internal pure returns (PackedUFixed18) {\n uint256 value = UFixed18.unwrap(a);\n if (value > type(uint128).max) revert UFixed18PackingOverflowError(value);\n return PackedUFixed18.wrap(uint128(value));\n }\n\n /**\n * @notice Returns whether the unsigned fixed-decimal is equal to zero.\n * @param a Unsigned fixed-decimal\n * @return Whether the unsigned fixed-decimal is zero.\n */\n function isZero(UFixed18 a) internal pure returns (bool) {\n return UFixed18.unwrap(a) == 0;\n }\n\n /**\n * @notice Adds two unsigned fixed-decimals `a` and `b` together\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Resulting summed unsigned fixed-decimal\n */\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n\n /**\n * @notice Subtracts unsigned fixed-decimal `b` from `a`\n * @param a Unsigned fixed-decimal to subtract from\n * @param b Unsigned fixed-decimal to subtract\n * @return Resulting subtracted unsigned fixed-decimal\n */\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n\n /**\n * @notice Multiplies two unsigned fixed-decimals `a` and `b` together\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Resulting multiplied unsigned fixed-decimal\n */\n function mul(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / BASE);\n }\n\n /**\n * @notice Divides unsigned fixed-decimal `a` by `b`\n * @param a Unsigned fixed-decimal to divide\n * @param b Unsigned fixed-decimal to divide by\n * @return Resulting divided unsigned fixed-decimal\n */\n function div(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) * BASE / UFixed18.unwrap(b));\n }\n\n /**\n * @notice Divides unsigned fixed-decimal `a` by `b`\n * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0` and `MAX` for `n/0`.\n * @param a Unsigned fixed-decimal to divide\n * @param b Unsigned fixed-decimal to divide by\n * @return Resulting divided unsigned fixed-decimal\n */\n function unsafeDiv(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n if (isZero(b)) {\n return isZero(a) ? ONE : MAX;\n } else {\n return div(a, b);\n }\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First unsigned fixed-decimal\n * @param b Unsigned number to multiply by\n * @param c Unsigned number to divide by\n * @return Resulting computation\n */\n function muldiv(UFixed18 a, uint256 b, uint256 c) internal pure returns (UFixed18) {\n return muldiv(a, UFixed18.wrap(b), UFixed18.wrap(c));\n }\n\n /**\n * @notice Computes a * b / c without loss of precision due to BASE conversion\n * @param a First unsigned fixed-decimal\n * @param b Unsigned fixed-decimal to multiply by\n * @param c Unsigned fixed-decimal to divide by\n * @return Resulting computation\n */\n function muldiv(UFixed18 a, UFixed18 b, UFixed18 c) internal pure returns (UFixed18) {\n return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / UFixed18.unwrap(c));\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is equal to `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is equal to `b`\n */\n function eq(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return compare(a, b) == 1;\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is greater than `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is greater than `b`\n */\n function gt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return compare(a, b) == 2;\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is less than `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is less than `b`\n */\n function lt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return compare(a, b) == 0;\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is greater than or equal to `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is greater than or equal to `b`\n */\n function gte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return gt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Returns whether unsigned fixed-decimal `a` is less than or equal to `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Whether `a` is less than or equal to `b`\n */\n function lte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\n return lt(a, b) || eq(a, b);\n }\n\n /**\n * @notice Compares the unsigned fixed-decimals `a` and `b`\n * @dev Returns: 2 for greater than\n * 1 for equal to\n * 0 for less than\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Compare result of `a` and `b`\n */\n function compare(UFixed18 a, UFixed18 b) internal pure returns (uint256) {\n (uint256 au, uint256 bu) = (UFixed18.unwrap(a), UFixed18.unwrap(b));\n if (au > bu) return 2;\n if (au < bu) return 0;\n return 1;\n }\n\n /**\n * @notice Returns a unsigned fixed-decimal representing the ratio of `a` over `b`\n * @param a First unsigned number\n * @param b Second unsigned number\n * @return Ratio of `a` over `b`\n */\n function ratio(uint256 a, uint256 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(a * BASE / b);\n }\n\n /**\n * @notice Returns the minimum of unsigned fixed-decimals `a` and `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Minimum of `a` and `b`\n */\n function min(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(Math.min(UFixed18.unwrap(a), UFixed18.unwrap(b)));\n }\n\n /**\n * @notice Returns the maximum of unsigned fixed-decimals `a` and `b`\n * @param a First unsigned fixed-decimal\n * @param b Second unsigned fixed-decimal\n * @return Maximum of `a` and `b`\n */\n function max(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\n return UFixed18.wrap(Math.max(UFixed18.unwrap(a), UFixed18.unwrap(b)));\n }\n\n /**\n * @notice Converts the unsigned fixed-decimal into an integer, truncating any decimal portion\n * @param a Unsigned fixed-decimal\n * @return Truncated unsigned number\n */\n function truncate(UFixed18 a) internal pure returns (uint256) {\n return UFixed18.unwrap(a) / BASE;\n }\n}\n\nlibrary UFixed18StorageLib {\n function read(UFixed18Storage self) internal view returns (UFixed18 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(UFixed18Storage self, UFixed18 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/storage/UStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../number/types/UFixed18.sol\";\n\n/// @dev Stored boolean slot\ntype BoolStorage is bytes32;\nusing BoolStorageLib for BoolStorage global;\n\n/// @dev Stored uint256 slot\ntype Uint256Storage is bytes32;\nusing Uint256StorageLib for Uint256Storage global;\n\n/// @dev Stored int256 slot\ntype Int256Storage is bytes32;\nusing Int256StorageLib for Int256Storage global;\n\n/// @dev Stored address slot\ntype AddressStorage is bytes32;\nusing AddressStorageLib for AddressStorage global;\n\n/// @dev Stored bytes32 slot\ntype Bytes32Storage is bytes32;\nusing Bytes32StorageLib for Bytes32Storage global;\n\n/**\n * @title BoolStorageLib\n * @notice Library to manage storage and retrival of a boolean at a fixed storage slot\n */\nlibrary BoolStorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored bool value\n */\n function read(BoolStorage self) internal view returns (bool value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value boolean value to store\n */\n function store(BoolStorage self, bool value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title Uint256StorageLib\n * @notice Library to manage storage and retrival of an uint256 at a fixed storage slot\n */\nlibrary Uint256StorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored uint256 value\n */\n function read(Uint256Storage self) internal view returns (uint256 value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value uint256 value to store\n */\n function store(Uint256Storage self, uint256 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title Int256StorageLib\n * @notice Library to manage storage and retrival of an int256 at a fixed storage slot\n */\nlibrary Int256StorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored int256 value\n */\n function read(Int256Storage self) internal view returns (int256 value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value int256 value to store\n */\n function store(Int256Storage self, int256 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title AddressStorageLib\n * @notice Library to manage storage and retrival of an address at a fixed storage slot\n */\nlibrary AddressStorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored address value\n */\n function read(AddressStorage self) internal view returns (address value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value address value to store\n */\n function store(AddressStorage self, address value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n\n/**\n * @title Bytes32StorageLib\n * @notice Library to manage storage and retrival of a bytes32 at a fixed storage slot\n */\nlibrary Bytes32StorageLib {\n /**\n * @notice Retrieves the stored value\n * @param self Storage slot\n * @return value Stored bytes32 value\n */\n function read(Bytes32Storage self) internal view returns (bytes32 value) {\n assembly {\n value := sload(self)\n }\n }\n\n /**\n * @notice Stores the value at the specific slot\n * @param self Storage slot\n * @param value bytes32 value to store\n */\n function store(Bytes32Storage self, bytes32 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/token/types/Token18.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../../number/types/UFixed18.sol\";\n\n/// @dev Token18\ntype Token18 is address;\nusing Token18Lib for Token18 global;\ntype Token18Storage is bytes32;\nusing Token18StorageLib for Token18Storage global;\n\n/**\n * @title Token18Lib\n * @notice Library to manage 18-decimal ERC20s that is compliant with the fixed-decimal types.\n * @dev Maintains significant gas savings over other Token implementations since no conversion take place\n */\nlibrary Token18Lib {\n using SafeERC20 for IERC20;\n\n Token18 public constant ZERO = Token18.wrap(address(0));\n\n /**\n * @notice Returns whether a token is the zero address\n * @param self Token to check for\n * @return Whether the token is the zero address\n */\n function isZero(Token18 self) internal pure returns (bool) {\n return Token18.unwrap(self) == Token18.unwrap(ZERO);\n }\n\n /**\n * @notice Returns whether the two tokens are equal\n * @param a First token to compare\n * @param b Second token to compare\n * @return Whether the two tokens are equal\n */\n function eq(Token18 a, Token18 b) internal pure returns (bool) {\n return Token18.unwrap(a) == Token18.unwrap(b);\n }\n\n /**\n * @notice Approves `grantee` to spend infinite tokens from the caller\n * @param self Token to transfer\n * @param grantee Address to allow spending\n */\n function approve(Token18 self, address grantee) internal {\n IERC20(Token18.unwrap(self)).safeApprove(grantee, type(uint256).max);\n }\n\n /**\n * @notice Approves `grantee` to spend `amount` tokens from the caller\n * @dev There are important race conditions to be aware of when using this function\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\n * @param self Token to transfer\n * @param grantee Address to allow spending\n * @param amount Amount of tokens to approve to spend\n */\n function approve(Token18 self, address grantee, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeApprove(grantee, UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Transfers all held tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to receive the tokens\n */\n function push(Token18 self, address recipient) internal {\n push(self, recipient, balanceOf(self, address(this)));\n }\n\n /**\n * @notice Transfers `amount` tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function push(Token18 self, address recipient, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeTransfer(recipient, UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param amount Amount of tokens to transfer\n */\n function pull(Token18 self, address benefactor, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, address(this), UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function pullTo(Token18 self, address benefactor, address recipient, UFixed18 amount) internal {\n IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, recipient, UFixed18.unwrap(amount));\n }\n\n /**\n * @notice Returns the name of the token\n * @param self Token to check for\n * @return Token name\n */\n function name(Token18 self) internal view returns (string memory) {\n return IERC20Metadata(Token18.unwrap(self)).name();\n }\n\n /**\n * @notice Returns the symbol of the token\n * @param self Token to check for\n * @return Token symbol\n */\n function symbol(Token18 self) internal view returns (string memory) {\n return IERC20Metadata(Token18.unwrap(self)).symbol();\n }\n\n /**\n * @notice Returns the `self` token balance of the caller\n * @param self Token to check for\n * @return Token balance of the caller\n */\n function balanceOf(Token18 self) internal view returns (UFixed18) {\n return balanceOf(self, address(this));\n }\n\n /**\n * @notice Returns the `self` token balance of `account`\n * @param self Token to check for\n * @param account Account to check\n * @return Token balance of the account\n */\n function balanceOf(Token18 self, address account) internal view returns (UFixed18) {\n return UFixed18.wrap(IERC20(Token18.unwrap(self)).balanceOf(account));\n }\n}\n\nlibrary Token18StorageLib {\n function read(Token18Storage self) internal view returns (Token18 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(Token18Storage self, Token18 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@equilibria/root/token/types/Token6.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"../../number/types/UFixed18.sol\";\n\n/// @dev Token6\ntype Token6 is address;\nusing Token6Lib for Token6 global;\ntype Token6Storage is bytes32;\nusing Token6StorageLib for Token6Storage global;\n\n/**\n * @title Token6Lib\n * @notice Library to manage 6-decimal ERC20s that is compliant with the fixed-decimal types.\n * @dev Automatically converts from Base-6 token amounts to Base-18 UFixed18 amounts, with optional rounding\n */\nlibrary Token6Lib {\n using SafeERC20 for IERC20;\n\n Token6 public constant ZERO = Token6.wrap(address(0));\n\n uint256 private constant OFFSET = 1e12;\n\n /**\n * @notice Returns whether a token is the zero address\n * @param self Token to check for\n * @return Whether the token is the zero address\n */\n function isZero(Token6 self) internal pure returns (bool) {\n return Token6.unwrap(self) == Token6.unwrap(ZERO);\n }\n\n /**\n * @notice Returns whether the two tokens are equal\n * @param a First token to compare\n * @param b Second token to compare\n * @return Whether the two tokens are equal\n */\n function eq(Token6 a, Token6 b) internal pure returns (bool) {\n return Token6.unwrap(a) == Token6.unwrap(b);\n }\n\n /**\n * @notice Approves `grantee` to spend infinite tokens from the caller\n * @param self Token to transfer\n * @param grantee Address to allow spending\n */\n function approve(Token6 self, address grantee) internal {\n IERC20(Token6.unwrap(self)).safeApprove(grantee, type(uint256).max);\n }\n\n /**\n * @notice Approves `grantee` to spend `amount` tokens from the caller\n * @dev There are important race conditions to be aware of when using this function\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\n * @param self Token to transfer\n * @param grantee Address to allow spending\n * @param amount Amount of tokens to approve to spend\n */\n function approve(Token6 self, address grantee, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, false));\n }\n\n /**\n * @notice Approves `grantee` to spend `amount` tokens from the caller\n * @dev There are important race conditions to be aware of when using this function\n with values other than 0. This will revert if moving from non-zero to non-zero amounts\n See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\n * @param self Token to transfer\n * @param grantee Address to allow spending\n * @param amount Amount of tokens to approve to spend\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function approve(Token6 self, address grantee, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Transfers all held tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to receive the tokens\n */\n function push(Token6 self, address recipient) internal {\n push(self, recipient, balanceOf(self, address(this)));\n }\n\n /**\n * @notice Transfers `amount` tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function push(Token6 self, address recipient, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, false));\n }\n\n /**\n * @notice Transfers `amount` tokens from the caller to the `recipient`\n * @param self Token to transfer\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function push(Token6 self, address recipient, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param amount Amount of tokens to transfer\n */\n function pull(Token6 self, address benefactor, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, false));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to the caller\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param amount Amount of tokens to transfer\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function pull(Token6 self, address benefactor, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n */\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, false));\n }\n\n /**\n * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\n * @dev Reverts if trying to pull Ether\n * @param self Token to transfer\n * @param benefactor Address to transfer tokens from\n * @param recipient Address to transfer tokens to\n * @param amount Amount of tokens to transfer\n * @param roundUp Whether to round decimal token amount up to the next unit\n */\n function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount, bool roundUp) internal {\n IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, roundUp));\n }\n\n /**\n * @notice Returns the name of the token\n * @param self Token to check for\n * @return Token name\n */\n function name(Token6 self) internal view returns (string memory) {\n return IERC20Metadata(Token6.unwrap(self)).name();\n }\n\n /**\n * @notice Returns the symbol of the token\n * @param self Token to check for\n * @return Token symbol\n */\n function symbol(Token6 self) internal view returns (string memory) {\n return IERC20Metadata(Token6.unwrap(self)).symbol();\n }\n\n /**\n * @notice Returns the `self` token balance of the caller\n * @param self Token to check for\n * @return Token balance of the caller\n */\n function balanceOf(Token6 self) internal view returns (UFixed18) {\n return balanceOf(self, address(this));\n }\n\n /**\n * @notice Returns the `self` token balance of `account`\n * @param self Token to check for\n * @param account Account to check\n * @return Token balance of the account\n */\n function balanceOf(Token6 self, address account) internal view returns (UFixed18) {\n return fromTokenAmount(IERC20(Token6.unwrap(self)).balanceOf(account));\n }\n\n /**\n * @notice Converts the unsigned fixed-decimal amount into the token amount according to\n * it's defined decimals\n * @dev Provides the ability to \"round up\" the token amount which is useful in situations where\n * are swapping one token for another and don't want to give away \"free\" units due to rounding\n * errors in the favor of the user.\n * @param amount Amount to convert\n * @param roundUp Whether to round decimal token amount up to the next unit\n * @return Normalized token amount\n */\n function toTokenAmount(UFixed18 amount, bool roundUp) private pure returns (uint256) {\n return roundUp ? Math.ceilDiv(UFixed18.unwrap(amount), OFFSET) : UFixed18.unwrap(amount) / OFFSET;\n }\n\n /**\n * @notice Converts the token amount into the unsigned fixed-decimal amount according to\n * it's defined decimals\n * @param amount Token amount to convert\n * @return Normalized unsigned fixed-decimal amount\n */\n function fromTokenAmount(uint256 amount) private pure returns (UFixed18) {\n return UFixed18.wrap(amount * OFFSET);\n }\n}\n\nlibrary Token6StorageLib {\n function read(Token6Storage self) internal view returns (Token6 value) {\n assembly {\n value := sload(self)\n }\n }\n\n function store(Token6Storage self, Token6 value) internal {\n assembly {\n sstore(self, value)\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/AccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerable.sol\";\nimport \"./AccessControl.sol\";\nimport \"../utils/structs/EnumerableSet.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControlEnumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol)\n\npragma solidity ^0.8.4;\n\nimport \"../CrossChainEnabled.sol\";\nimport \"./LibArbitrumL2.sol\";\n\n/**\n * @dev https://arbitrum.io/[Arbitrum] specialization or the\n * {CrossChainEnabled} abstraction the L2 side (arbitrum).\n *\n * This version should only be deployed on L2 to process cross-chain messages\n * originating from L1. For the other side, use {CrossChainEnabledArbitrumL1}.\n *\n * Arbitrum L2 includes the `ArbSys` contract at a fixed address. Therefore,\n * this specialization of {CrossChainEnabled} does not include a constructor.\n *\n * _Available since v4.6._\n *\n * WARNING: There is currently a bug in Arbitrum that causes this contract to\n * fail to detect cross-chain calls when deployed behind a proxy. This will be\n * fixed when the network is upgraded to Arbitrum Nitro, currently scheduled for\n * August 31st 2022.\n */\nabstract contract CrossChainEnabledArbitrumL2 is CrossChainEnabled {\n /**\n * @dev see {CrossChainEnabled-_isCrossChain}\n */\n function _isCrossChain() internal view virtual override returns (bool) {\n return LibArbitrumL2.isCrossChain(LibArbitrumL2.ARBSYS);\n }\n\n /**\n * @dev see {CrossChainEnabled-_crossChainSender}\n */\n function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {\n return LibArbitrumL2.crossChainSender(LibArbitrumL2.ARBSYS);\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL2.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/LibArbitrumL2.sol)\n\npragma solidity ^0.8.4;\n\nimport {IArbSys as ArbitrumL2_Bridge} from \"../../vendor/arbitrum/IArbSys.sol\";\nimport \"../errors.sol\";\n\n/**\n * @dev Primitives for cross-chain aware contracts for\n * https://arbitrum.io/[Arbitrum].\n *\n * This version should only be used on L2 to process cross-chain messages\n * originating from L1. For the other side, use {LibArbitrumL1}.\n *\n * WARNING: There is currently a bug in Arbitrum that causes this contract to\n * fail to detect cross-chain calls when deployed behind a proxy. This will be\n * fixed when the network is upgraded to Arbitrum Nitro, currently scheduled for\n * August 31st 2022.\n */\nlibrary LibArbitrumL2 {\n /**\n * @dev Returns whether the current function call is the result of a\n * cross-chain message relayed by `arbsys`.\n */\n address public constant ARBSYS = 0x0000000000000000000000000000000000000064;\n\n function isCrossChain(address arbsys) internal view returns (bool) {\n return ArbitrumL2_Bridge(arbsys).wasMyCallersAddressAliased();\n }\n\n /**\n * @dev Returns the address of the sender that triggered the current\n * cross-chain message through `arbsys`.\n *\n * NOTE: {isCrossChain} should be checked before trying to recover the\n * sender, as it will revert with `NotCrossChainCall` if the current\n * function call is not the result of a cross-chain message.\n */\n function crossChainSender(address arbsys) internal view returns (address) {\n if (!isCrossChain(arbsys)) revert NotCrossChainCall();\n\n return ArbitrumL2_Bridge(arbsys).myCallersAddressWithoutAliasing();\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/CrossChainEnabled.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/CrossChainEnabled.sol)\n\npragma solidity ^0.8.4;\n\nimport \"./errors.sol\";\n\n/**\n * @dev Provides information for building cross-chain aware contracts. This\n * abstract contract provides accessors and modifiers to control the execution\n * flow when receiving cross-chain messages.\n *\n * Actual implementations of cross-chain aware contracts, which are based on\n * this abstraction, will have to inherit from a bridge-specific\n * specialization. Such specializations are provided under\n * `crosschain//CrossChainEnabled.sol`.\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabled {\n /**\n * @dev Throws if the current function call is not the result of a\n * cross-chain execution.\n */\n modifier onlyCrossChain() {\n if (!_isCrossChain()) revert NotCrossChainCall();\n _;\n }\n\n /**\n * @dev Throws if the current function call is not the result of a\n * cross-chain execution initiated by `account`.\n */\n modifier onlyCrossChainSender(address expected) {\n address actual = _crossChainSender();\n if (expected != actual) revert InvalidCrossChainSender(actual, expected);\n _;\n }\n\n /**\n * @dev Returns whether the current function call is the result of a\n * cross-chain message.\n */\n function _isCrossChain() internal view virtual returns (bool);\n\n /**\n * @dev Returns the address of the sender of the cross-chain message that\n * triggered the current function call.\n *\n * IMPORTANT: Should revert with `NotCrossChainCall` if the current function\n * call is not the result of a cross-chain message.\n */\n function _crossChainSender() internal view virtual returns (address);\n}\n" + }, + "@openzeppelin/contracts/crosschain/errors.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol)\n\npragma solidity ^0.8.4;\n\nerror NotCrossChainCall();\nerror InvalidCrossChainSender(address actual, address expected);\n" + }, + "@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/CrossChainEnabledOptimism.sol)\n\npragma solidity ^0.8.4;\n\nimport \"../CrossChainEnabled.sol\";\nimport \"./LibOptimism.sol\";\n\n/**\n * @dev https://www.optimism.io/[Optimism] specialization or the\n * {CrossChainEnabled} abstraction.\n *\n * The messenger (`CrossDomainMessenger`) contract is provided and maintained by\n * the optimism team. You can find the address of this contract on mainnet and\n * kovan in the https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/deployments[deployments section of Optimism monorepo].\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabledOptimism is CrossChainEnabled {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n address private immutable _messenger;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(address messenger) {\n _messenger = messenger;\n }\n\n /**\n * @dev see {CrossChainEnabled-_isCrossChain}\n */\n function _isCrossChain() internal view virtual override returns (bool) {\n return LibOptimism.isCrossChain(_messenger);\n }\n\n /**\n * @dev see {CrossChainEnabled-_crossChainSender}\n */\n function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {\n return LibOptimism.crossChainSender(_messenger);\n }\n}\n" + }, + "@openzeppelin/contracts/crosschain/optimism/LibOptimism.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/LibOptimism.sol)\n\npragma solidity ^0.8.4;\n\nimport {ICrossDomainMessenger as Optimism_Bridge} from \"../../vendor/optimism/ICrossDomainMessenger.sol\";\nimport \"../errors.sol\";\n\n/**\n * @dev Primitives for cross-chain aware contracts for https://www.optimism.io/[Optimism].\n * See the https://community.optimism.io/docs/developers/bridge/messaging/#accessing-msg-sender[documentation]\n * for the functionality used here.\n */\nlibrary LibOptimism {\n /**\n * @dev Returns whether the current function call is the result of a\n * cross-chain message relayed by `messenger`.\n */\n function isCrossChain(address messenger) internal view returns (bool) {\n return msg.sender == messenger;\n }\n\n /**\n * @dev Returns the address of the sender that triggered the current\n * cross-chain message through `messenger`.\n *\n * NOTE: {isCrossChain} should be checked before trying to recover the\n * sender, as it will revert with `NotCrossChainCall` if the current\n * function call is not the result of a cross-chain message.\n */\n function crossChainSender(address messenger) internal view returns (address) {\n if (!isCrossChain(messenger)) revert NotCrossChainCall();\n\n return Optimism_Bridge(messenger).xDomainMessageSender();\n }\n}\n" + }, + "@openzeppelin/contracts/governance/TimelockController.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (governance/TimelockController.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../access/AccessControl.sol\";\nimport \"../token/ERC721/IERC721Receiver.sol\";\nimport \"../token/ERC1155/IERC1155Receiver.sol\";\nimport \"../utils/Address.sol\";\n\n/**\n * @dev Contract module which acts as a timelocked controller. When set as the\n * owner of an `Ownable` smart contract, it enforces a timelock on all\n * `onlyOwner` maintenance operations. This gives time for users of the\n * controlled contract to exit before a potentially dangerous maintenance\n * operation is applied.\n *\n * By default, this contract is self administered, meaning administration tasks\n * have to go through the timelock process. The proposer (resp executor) role\n * is in charge of proposing (resp executing) operations. A common use case is\n * to position this {TimelockController} as the owner of a smart contract, with\n * a multisig or a DAO as the sole proposer.\n *\n * _Available since v3.3._\n */\ncontract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver {\n bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256(\"TIMELOCK_ADMIN_ROLE\");\n bytes32 public constant PROPOSER_ROLE = keccak256(\"PROPOSER_ROLE\");\n bytes32 public constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n bytes32 public constant CANCELLER_ROLE = keccak256(\"CANCELLER_ROLE\");\n uint256 internal constant _DONE_TIMESTAMP = uint256(1);\n\n mapping(bytes32 => uint256) private _timestamps;\n uint256 private _minDelay;\n\n /**\n * @dev Emitted when a call is scheduled as part of operation `id`.\n */\n event CallScheduled(\n bytes32 indexed id,\n uint256 indexed index,\n address target,\n uint256 value,\n bytes data,\n bytes32 predecessor,\n uint256 delay\n );\n\n /**\n * @dev Emitted when a call is performed as part of operation `id`.\n */\n event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);\n\n /**\n * @dev Emitted when operation `id` is cancelled.\n */\n event Cancelled(bytes32 indexed id);\n\n /**\n * @dev Emitted when the minimum delay for future operations is modified.\n */\n event MinDelayChange(uint256 oldDuration, uint256 newDuration);\n\n /**\n * @dev Initializes the contract with the following parameters:\n *\n * - `minDelay`: initial minimum delay for operations\n * - `proposers`: accounts to be granted proposer and canceller roles\n * - `executors`: accounts to be granted executor role\n * - `admin`: optional account to be granted admin role; disable with zero address\n *\n * IMPORTANT: The optional admin can aid with initial configuration of roles after deployment\n * without being subject to delay, but this role should be subsequently renounced in favor of\n * administration through timelocked proposals. Previous versions of this contract would assign\n * this admin to the deployer automatically and should be renounced as well.\n */\n constructor(\n uint256 minDelay,\n address[] memory proposers,\n address[] memory executors,\n address admin\n ) {\n _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE);\n\n // self administration\n _setupRole(TIMELOCK_ADMIN_ROLE, address(this));\n\n // optional admin\n if (admin != address(0)) {\n _setupRole(TIMELOCK_ADMIN_ROLE, admin);\n }\n\n // register proposers and cancellers\n for (uint256 i = 0; i < proposers.length; ++i) {\n _setupRole(PROPOSER_ROLE, proposers[i]);\n _setupRole(CANCELLER_ROLE, proposers[i]);\n }\n\n // register executors\n for (uint256 i = 0; i < executors.length; ++i) {\n _setupRole(EXECUTOR_ROLE, executors[i]);\n }\n\n _minDelay = minDelay;\n emit MinDelayChange(0, minDelay);\n }\n\n /**\n * @dev Modifier to make a function callable only by a certain role. In\n * addition to checking the sender's role, `address(0)` 's role is also\n * considered. Granting a role to `address(0)` is equivalent to enabling\n * this role for everyone.\n */\n modifier onlyRoleOrOpenRole(bytes32 role) {\n if (!hasRole(role, address(0))) {\n _checkRole(role, _msgSender());\n }\n _;\n }\n\n /**\n * @dev Contract might receive/hold ETH as part of the maintenance process.\n */\n receive() external payable {}\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, AccessControl) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns whether an id correspond to a registered operation. This\n * includes both Pending, Ready and Done operations.\n */\n function isOperation(bytes32 id) public view virtual returns (bool registered) {\n return getTimestamp(id) > 0;\n }\n\n /**\n * @dev Returns whether an operation is pending or not.\n */\n function isOperationPending(bytes32 id) public view virtual returns (bool pending) {\n return getTimestamp(id) > _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Returns whether an operation is ready or not.\n */\n function isOperationReady(bytes32 id) public view virtual returns (bool ready) {\n uint256 timestamp = getTimestamp(id);\n return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;\n }\n\n /**\n * @dev Returns whether an operation is done or not.\n */\n function isOperationDone(bytes32 id) public view virtual returns (bool done) {\n return getTimestamp(id) == _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Returns the timestamp at with an operation becomes ready (0 for\n * unset operations, 1 for done operations).\n */\n function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {\n return _timestamps[id];\n }\n\n /**\n * @dev Returns the minimum delay for an operation to become valid.\n *\n * This value can be changed by executing an operation that calls `updateDelay`.\n */\n function getMinDelay() public view virtual returns (uint256 duration) {\n return _minDelay;\n }\n\n /**\n * @dev Returns the identifier of an operation containing a single\n * transaction.\n */\n function hashOperation(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt\n ) public pure virtual returns (bytes32 hash) {\n return keccak256(abi.encode(target, value, data, predecessor, salt));\n }\n\n /**\n * @dev Returns the identifier of an operation containing a batch of\n * transactions.\n */\n function hashOperationBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt\n ) public pure virtual returns (bytes32 hash) {\n return keccak256(abi.encode(targets, values, payloads, predecessor, salt));\n }\n\n /**\n * @dev Schedule an operation containing a single transaction.\n *\n * Emits a {CallScheduled} event.\n *\n * Requirements:\n *\n * - the caller must have the 'proposer' role.\n */\n function schedule(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt,\n uint256 delay\n ) public virtual onlyRole(PROPOSER_ROLE) {\n bytes32 id = hashOperation(target, value, data, predecessor, salt);\n _schedule(id, delay);\n emit CallScheduled(id, 0, target, value, data, predecessor, delay);\n }\n\n /**\n * @dev Schedule an operation containing a batch of transactions.\n *\n * Emits one {CallScheduled} event per transaction in the batch.\n *\n * Requirements:\n *\n * - the caller must have the 'proposer' role.\n */\n function scheduleBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt,\n uint256 delay\n ) public virtual onlyRole(PROPOSER_ROLE) {\n require(targets.length == values.length, \"TimelockController: length mismatch\");\n require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n _schedule(id, delay);\n for (uint256 i = 0; i < targets.length; ++i) {\n emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);\n }\n }\n\n /**\n * @dev Schedule an operation that is to becomes valid after a given delay.\n */\n function _schedule(bytes32 id, uint256 delay) private {\n require(!isOperation(id), \"TimelockController: operation already scheduled\");\n require(delay >= getMinDelay(), \"TimelockController: insufficient delay\");\n _timestamps[id] = block.timestamp + delay;\n }\n\n /**\n * @dev Cancel an operation.\n *\n * Requirements:\n *\n * - the caller must have the 'canceller' role.\n */\n function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {\n require(isOperationPending(id), \"TimelockController: operation cannot be cancelled\");\n delete _timestamps[id];\n\n emit Cancelled(id);\n }\n\n /**\n * @dev Execute an (ready) operation containing a single transaction.\n *\n * Emits a {CallExecuted} event.\n *\n * Requirements:\n *\n * - the caller must have the 'executor' role.\n */\n // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n // thus any modifications to the operation during reentrancy should be caught.\n // slither-disable-next-line reentrancy-eth\n function execute(\n address target,\n uint256 value,\n bytes calldata payload,\n bytes32 predecessor,\n bytes32 salt\n ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n bytes32 id = hashOperation(target, value, payload, predecessor, salt);\n\n _beforeCall(id, predecessor);\n _execute(target, value, payload);\n emit CallExecuted(id, 0, target, value, payload);\n _afterCall(id);\n }\n\n /**\n * @dev Execute an (ready) operation containing a batch of transactions.\n *\n * Emits one {CallExecuted} event per transaction in the batch.\n *\n * Requirements:\n *\n * - the caller must have the 'executor' role.\n */\n function executeBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt\n ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n require(targets.length == values.length, \"TimelockController: length mismatch\");\n require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n\n _beforeCall(id, predecessor);\n for (uint256 i = 0; i < targets.length; ++i) {\n address target = targets[i];\n uint256 value = values[i];\n bytes calldata payload = payloads[i];\n _execute(target, value, payload);\n emit CallExecuted(id, i, target, value, payload);\n }\n _afterCall(id);\n }\n\n /**\n * @dev Execute an operation's call.\n */\n function _execute(\n address target,\n uint256 value,\n bytes calldata data\n ) internal virtual {\n (bool success, ) = target.call{value: value}(data);\n require(success, \"TimelockController: underlying transaction reverted\");\n }\n\n /**\n * @dev Checks before execution of an operation's calls.\n */\n function _beforeCall(bytes32 id, bytes32 predecessor) private view {\n require(isOperationReady(id), \"TimelockController: operation is not ready\");\n require(predecessor == bytes32(0) || isOperationDone(predecessor), \"TimelockController: missing dependency\");\n }\n\n /**\n * @dev Checks after execution of an operation's calls.\n */\n function _afterCall(bytes32 id) private {\n require(isOperationReady(id), \"TimelockController: operation is not ready\");\n _timestamps[id] = _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Changes the minimum timelock duration for future operations.\n *\n * Emits a {MinDelayChange} event.\n *\n * Requirements:\n *\n * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing\n * an operation where the timelock is the target and the data is the ABI-encoded call to this function.\n */\n function updateDelay(uint256 newDelay) external virtual {\n require(msg.sender == address(this), \"TimelockController: caller must be timelock\");\n emit MinDelayChange(_minDelay, newDelay);\n _minDelay = newDelay;\n }\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155Received}.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n constructor(address implementation_) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../security/Pausable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n */\nabstract contract ERC20Pausable is ERC20, Pausable {\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetMinterPauser.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../extensions/ERC20Burnable.sol\";\nimport \"../extensions/ERC20Pausable.sol\";\nimport \"../../../access/AccessControlEnumerable.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev {ERC20} token, including:\n *\n * - ability for holders to burn (destroy) their tokens\n * - a minter role that allows for token minting (creation)\n * - a pauser role that allows to stop all token transfers\n *\n * This contract uses {AccessControl} to lock permissioned functions using the\n * different roles - head to its documentation for details.\n *\n * The account that deploys the contract will be granted the minter and pauser\n * roles, as well as the default admin role, which will let it grant both minter\n * and pauser roles to other accounts.\n *\n * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._\n */\ncontract ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable {\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n /**\n * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the\n * account that deploys the contract.\n *\n * See {ERC20-constructor}.\n */\n constructor(string memory name, string memory symbol) ERC20(name, symbol) {\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\n\n _setupRole(MINTER_ROLE, _msgSender());\n _setupRole(PAUSER_ROLE, _msgSender());\n }\n\n /**\n * @dev Creates `amount` new tokens for `to`.\n *\n * See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the `MINTER_ROLE`.\n */\n function mint(address to, uint256 amount) public virtual {\n require(hasRole(MINTER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have minter role to mint\");\n _mint(to, amount);\n }\n\n /**\n * @dev Pauses all token transfers.\n *\n * See {ERC20Pausable} and {Pausable-_pause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function pause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have pauser role to pause\");\n _pause();\n }\n\n /**\n * @dev Unpauses all token transfers.\n *\n * See {ERC20Pausable} and {Pausable-_unpause}.\n *\n * Requirements:\n *\n * - the caller must have the `PAUSER_ROLE`.\n */\n function unpause() public virtual {\n require(hasRole(PAUSER_ROLE, _msgSender()), \"ERC20PresetMinterPauser: must have pauser role to unpause\");\n _unpause();\n }\n\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override(ERC20, ERC20Pausable) {\n super._beforeTokenTransfer(from, to, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/vendor/arbitrum/IArbSys.sol": { + "content": "// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n// OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IArbSys.sol)\n\npragma solidity >=0.4.21 <0.9.0;\n\n/**\n * @title System level functionality\n * @notice For use by contracts to interact with core L2-specific functionality.\n * Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064.\n */\ninterface IArbSys {\n /**\n * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)\n * @return block number as int\n */\n function arbBlockNumber() external view returns (uint256);\n\n /**\n * @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum)\n * @return block hash\n */\n function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32);\n\n /**\n * @notice Gets the rollup's unique chain identifier\n * @return Chain identifier as int\n */\n function arbChainID() external view returns (uint256);\n\n /**\n * @notice Get internal version number identifying an ArbOS build\n * @return version number as int\n */\n function arbOSVersion() external view returns (uint256);\n\n /**\n * @notice Returns 0 since Nitro has no concept of storage gas\n * @return uint 0\n */\n function getStorageGasAvailable() external view returns (uint256);\n\n /**\n * @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract)\n * @dev this call has been deprecated and may be removed in a future release\n * @return true if current execution frame is not a call by another L2 contract\n */\n function isTopLevelCall() external view returns (bool);\n\n /**\n * @notice map L1 sender contract address to its L2 alias\n * @param sender sender address\n * @param unused argument no longer used\n * @return aliased sender address\n */\n function mapL1SenderContractAddressToL2Alias(address sender, address unused) external pure returns (address);\n\n /**\n * @notice check if the caller (of this caller of this) is an aliased L1 contract address\n * @return true iff the caller's address is an alias for an L1 contract address\n */\n function wasMyCallersAddressAliased() external view returns (bool);\n\n /**\n * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing\n * @return address of the caller's caller, without applying L1 contract address aliasing\n */\n function myCallersAddressWithoutAliasing() external view returns (address);\n\n /**\n * @notice Send given amount of Eth to dest from sender.\n * This is a convenience function, which is equivalent to calling sendTxToL1 with empty data.\n * @param destination recipient address on L1\n * @return unique identifier for this L2-to-L1 transaction.\n */\n function withdrawEth(address destination) external payable returns (uint256);\n\n /**\n * @notice Send a transaction to L1\n * @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data\n * to a contract address without any code (as enforced by the Bridge contract).\n * @param destination recipient address on L1\n * @param data (optional) calldata for L1 contract call\n * @return a unique identifier for this L2-to-L1 transaction.\n */\n function sendTxToL1(address destination, bytes calldata data) external payable returns (uint256);\n\n /**\n * @notice Get send Merkle tree state\n * @return size number of sends in the history\n * @return root root hash of the send history\n * @return partials hashes of partial subtrees in the send history tree\n */\n function sendMerkleTreeState()\n external\n view\n returns (\n uint256 size,\n bytes32 root,\n bytes32[] memory partials\n );\n\n /**\n * @notice creates a send txn from L2 to L1\n * @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf\n */\n event L2ToL1Tx(\n address caller,\n address indexed destination,\n uint256 indexed hash,\n uint256 indexed position,\n uint256 arbBlockNum,\n uint256 ethBlockNum,\n uint256 timestamp,\n uint256 callvalue,\n bytes data\n );\n\n /// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade\n event L2ToL1Transaction(\n address caller,\n address indexed destination,\n uint256 indexed uniqueId,\n uint256 indexed batchNumber,\n uint256 indexInBatch,\n uint256 arbBlockNum,\n uint256 ethBlockNum,\n uint256 timestamp,\n uint256 callvalue,\n bytes data\n );\n\n /**\n * @notice logs a merkle branch for proof synthesis\n * @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event\n * @param hash the merkle hash\n * @param position = (level << 192) + leaf\n */\n event SendMerkleUpdate(uint256 indexed reserved, bytes32 indexed hash, uint256 indexed position);\n}\n" + }, + "@openzeppelin/contracts/vendor/optimism/ICrossDomainMessenger.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (vendor/optimism/ICrossDomainMessenger.sol)\npragma solidity >0.5.0 <0.9.0;\n\n/**\n * @title ICrossDomainMessenger\n */\ninterface ICrossDomainMessenger {\n /**********\n * Events *\n **********/\n\n event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);\n event RelayedMessage(bytes32 indexed msgHash);\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /*************\n * Variables *\n *************/\n\n function xDomainMessageSender() external view returns (address);\n\n /********************\n * Public Functions *\n ********************/\n\n /**\n * Sends a cross domain message to the target messenger.\n * @param _target Target contract address.\n * @param _message Message to send to the target.\n * @param _gasLimit Gas limit for the provided message.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _gasLimit\n ) external;\n}\n" + }, + "contracts/collateral/Collateral.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/root/control/unstructured/UReentrancyGuard.sol\";\nimport \"../interfaces/ICollateral.sol\";\nimport \"./types/OptimisticLedger.sol\";\nimport \"../controller/UControllerProvider.sol\";\n\n/**\n * @title Collateral\n * @notice Manages logic and state for all collateral accounts in the protocol.\n */\ncontract Collateral is ICollateral, UInitializable, UControllerProvider, UReentrancyGuard {\n /// @dev ERC20 stablecoin for collateral\n Token18 public immutable token;\n\n /// @dev Per product collateral state\n mapping(IProduct => OptimisticLedger) private _products;\n\n /// @dev Protocol and product fees collected, but not yet claimed\n mapping(address => UFixed18) public fees;\n\n /**\n * @notice Initializes the immutable contract state\n * @dev Called at implementation instantiate and constant for that implementation.\n * @param token_ Collateral ERC20 stablecoin address\n */\n constructor(Token18 token_) {\n token = token_;\n }\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n * @param controller_ Factory contract address\n */\n function initialize(IController controller_) external initializer(1) {\n __UControllerProvider__initialize(controller_);\n __UReentrancyGuard__initialize();\n }\n\n /**\n * @notice Deposits `amount` collateral from `msg.sender` to `account`'s `product`\n * account\n * @param account Account to deposit the collateral for\n * @param product Product to credit the collateral to\n * @param amount Amount of collateral to deposit\n */\n function depositTo(address account, IProduct product, UFixed18 amount)\n external\n nonReentrant\n notPaused\n notZeroAddress(account)\n isProduct(product)\n collateralInvariant(account, product)\n {\n _products[product].creditAccount(account, amount);\n token.pull(msg.sender, amount);\n\n emit Deposit(account, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` collateral from `msg.sender`'s `product` account\n * and sends it to `receiver`\n * @param receiver Account to withdraw the collateral to\n * @param product Product to withdraw the collateral from\n * @param amount Amount of collateral to withdraw\n */\n function withdrawTo(address receiver, IProduct product, UFixed18 amount) external {\n withdrawFrom(msg.sender, receiver, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` collateral from `account`'s `product` account\n * and sends it to `receiver`\n * @param account Account to withdraw the collateral from\n * @param receiver Account to withdraw the collateral to\n * @param product Product to withdraw the collateral from\n * @param amount Amount of collateral to withdraw\n */\n function withdrawFrom(address account, address receiver, IProduct product, UFixed18 amount)\n public\n nonReentrant\n notPaused\n notZeroAddress(receiver)\n isProduct(product)\n onlyAccountOrMultiInvoker(account)\n settleForAccount(account, product)\n collateralInvariant(account, product)\n maintenanceInvariant(account, product)\n {\n amount = amount.eq(UFixed18Lib.MAX) ? collateral(account, product) : amount;\n _products[product].debitAccount(account, amount);\n token.push(receiver, amount);\n\n emit Withdrawal(account, product, amount);\n }\n\n /**\n * @notice Liquidates `account`'s `product` collateral account\n * @dev Account must be under-collateralized, fee returned immediately to `msg.sender`\n * @param account Account to liquidate\n * @param product Product to liquidate for\n */\n function liquidate(address account, IProduct product)\n external\n nonReentrant\n notPaused\n isProduct(product)\n settleForAccount(account, product)\n {\n if (product.isLiquidating(account)) revert CollateralAccountLiquidatingError(account);\n\n UFixed18 totalMaintenance = product.maintenance(account);\n UFixed18 totalCollateral = collateral(account, product);\n\n if (!totalMaintenance.gt(totalCollateral))\n revert CollateralCantLiquidate(totalMaintenance, totalCollateral);\n\n product.closeAll(account);\n\n // claim fee\n UFixed18 liquidationFee = controller().liquidationFee();\n // If maintenance is less than minCollateral, use minCollateral for fee amount\n UFixed18 collateralForFee = UFixed18Lib.max(totalMaintenance, controller().minCollateral());\n UFixed18 fee = UFixed18Lib.min(totalCollateral, collateralForFee.mul(liquidationFee));\n\n _products[product].debitAccount(account, fee);\n token.push(msg.sender, fee);\n\n emit Liquidation(account, product, msg.sender, fee);\n }\n\n /**\n * @notice Credits `amount` to `account`'s collateral account\n * @dev Callable only by the corresponding product as part of the settlement flywheel.\n * Moves collateral within a product, any collateral leaving the product due to\n * fees has already been accounted for in the settleProduct flywheel.\n * Debits in excess of the account balance get recorded as shortfall, and can be\n * resolved by the product owner as needed.\n * @param account Account to credit\n * @param amount Amount to credit the account (can be negative)\n */\n function settleAccount(address account, Fixed18 amount) external onlyProduct {\n IProduct product = IProduct(msg.sender);\n\n UFixed18 newShortfall = _products[product].settleAccount(account, amount);\n\n emit AccountSettle(product, account, amount, newShortfall);\n }\n\n /**\n * @notice Debits `amount` from product's total collateral account\n * @dev Callable only by the corresponding product as part of the settlement flywheel\n * Removes collateral from the product as fees.\n * @param amount Amount to debit from the account\n */\n function settleProduct(UFixed18 amount) external onlyProduct {\n (IProduct product, IController controller) = (IProduct(msg.sender), controller());\n\n address protocolTreasury = controller.treasury();\n address productTreasury = controller.treasury(product);\n\n UFixed18 protocolFee = amount.mul(controller.protocolFee());\n UFixed18 productFee = amount.sub(protocolFee);\n\n _products[product].debit(amount);\n fees[protocolTreasury] = fees[protocolTreasury].add(protocolFee);\n fees[productTreasury] = fees[productTreasury].add(productFee);\n\n emit ProductSettle(product, protocolFee, productFee);\n }\n\n /**\n * @notice Returns the balance of `account`'s `product` collateral account\n * @param account Account to return for\n * @param product Product to return for\n * @return The balance of the collateral account\n */\n function collateral(address account, IProduct product) public view returns (UFixed18) {\n return _products[product].balances[account];\n }\n\n /**\n * @notice Returns the total balance of `product`'s collateral\n * @param product Product to return for\n * @return The total balance of collateral in the product\n */\n function collateral(IProduct product) external view returns (UFixed18) {\n return _products[product].total;\n }\n\n /**\n * @notice Returns the current shortfall of `product`'s collateral\n * @param product Product to return for\n * @return The current shortfall of the product\n */\n function shortfall(IProduct product) external view returns (UFixed18) {\n return _products[product].shortfall;\n }\n\n /**\n * @notice Returns whether `account`'s `product` collateral account can be liquidated\n * @param account Account to return for\n * @param product Product to return for\n * @return Whether the account can be liquidated\n */\n function liquidatable(address account, IProduct product) external view returns (bool) {\n if (product.isLiquidating(account)) return false;\n\n return product.maintenance(account).gt(collateral(account, product));\n }\n\n /**\n * @notice Returns whether `account`'s `product` collateral account can be liquidated\n * after the next oracle version settlement\n * @dev Takes into account the current pre-position on the account\n * @param account Account to return for\n * @param product Product to return for\n * @return Whether the account can be liquidated\n */\n function liquidatableNext(address account, IProduct product) external view returns (bool) {\n return product.maintenanceNext(account).gt(collateral(account, product));\n }\n\n /**\n * @notice Injects additional collateral into a product to resolve shortfall\n * @dev Shortfall is a measure of settled insolvency in the market\n * This hook can be used by the product owner or an insurance fund to re-capitalize an insolvent market\n * @param product Product to resolve shortfall for\n * @param amount Amount of shortfall to resolve\n */\n function resolveShortfall(IProduct product, UFixed18 amount) external isProduct(product) notPaused {\n _products[product].resolve(amount);\n token.pull(msg.sender, amount);\n\n emit ShortfallResolution(product, amount);\n }\n\n /**\n * @notice Claims all of `msg.sender`'s fees\n */\n function claimFee() external notPaused {\n UFixed18 amount = fees[msg.sender];\n\n fees[msg.sender] = UFixed18Lib.ZERO;\n token.push(msg.sender, amount);\n\n emit FeeClaim(msg.sender, amount);\n }\n\n /// @dev Ensure that the address is non-zero\n modifier notZeroAddress(address account) {\n if (account == address(0)) revert CollateralZeroAddressError();\n\n _;\n }\n\n /// @dev Ensure that the user has sufficient margin for both current and next maintenance\n modifier maintenanceInvariant(address account, IProduct product) {\n _;\n\n UFixed18 maintenance = product.maintenance(account);\n UFixed18 maintenanceNext = product.maintenanceNext(account);\n\n if (UFixed18Lib.max(maintenance, maintenanceNext).gt(collateral(account, product)))\n revert CollateralInsufficientCollateralError();\n }\n\n /// @dev Ensure that the account is either empty or above the collateral minimum\n modifier collateralInvariant(address account, IProduct product) {\n _;\n\n UFixed18 accountCollateral = collateral(account, product);\n if (!accountCollateral.isZero() && accountCollateral.lt(controller().minCollateral()))\n revert CollateralUnderLimitError();\n }\n\n /// @dev Helper to fully settle an account's state\n modifier settleForAccount(address account, IProduct product) {\n product.settleAccount(account);\n\n _;\n }\n}\n" + }, + "contracts/collateral/types/OptimisticLedger.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\n\n/// @dev OptimisticLedger type\nstruct OptimisticLedger {\n /// @dev Individual account collateral balances\n mapping(address => UFixed18) balances;\n\n /// @dev Total ledger collateral balance\n UFixed18 total;\n\n /// @dev Total ledger collateral shortfall\n UFixed18 shortfall;\n}\nusing OptimisticLedgerLib for OptimisticLedger global;\n\n/**\n * @title OptimisticLedgerLib\n * @notice Library that manages a global vs account ledger where the global ledger is settled separately,\n * and ahead of, the user-level accounts.\n * @dev Ensures that no more collateral leaves the ledger than goes it, while allowing user-level accounts\n * to settle as a follow up step. Overdrafts on the user-level are accounted as \"shortall\". Shortfall\n * in the system is the quantity of insolvency that can be optionally resolved by the ledger owner.\n * Until the shortfall is resolved, collateral may be withdrawn from the ledger on a FCFS basis. However\n * once the ledger total has been depleted, users will not be able to withdraw even if they have non-zero\n * user level balances until the shortfall is resolved, recapitalizing the ledger.\n */\nlibrary OptimisticLedgerLib {\n /**\n * @notice Credits `account` with `amount` collateral\n * @param self The struct to operate on\n * @param account Account to credit collateral to\n * @param amount Amount of collateral to credit\n */\n function creditAccount(OptimisticLedger storage self, address account, UFixed18 amount) internal {\n self.balances[account] = self.balances[account].add(amount);\n self.total = self.total.add(amount);\n }\n\n /**\n * @notice Debits `account` `amount` collateral\n * @param self The struct to operate on\n * @param account Account to debit collateral from\n * @param amount Amount of collateral to debit\n */\n function debitAccount(OptimisticLedger storage self, address account, UFixed18 amount) internal {\n self.balances[account] = self.balances[account].sub(amount);\n self.total = self.total.sub(amount);\n }\n\n /**\n * @notice Credits `account` with `amount` collateral\n * @dev Funds come from inside the product, not totals are updated\n * Shortfall is created if more funds are debited from an account than exist\n * @param self The struct to operate on\n * @param account Account to credit collateral to\n * @param amount Amount of collateral to credit\n * @return newShortfall Any new shortfall incurred during this settlement\n */\n function settleAccount(OptimisticLedger storage self, address account, Fixed18 amount)\n internal returns (UFixed18 newShortfall) {\n Fixed18 newBalance = Fixed18Lib.from(self.balances[account]).add(amount);\n\n if (newBalance.sign() == -1) {\n newShortfall = newBalance.abs();\n newBalance = Fixed18Lib.ZERO;\n }\n\n self.balances[account] = newBalance.abs();\n self.shortfall = self.shortfall.add(newShortfall);\n }\n\n /**\n * @notice Debits ledger globally `amount` collateral\n * @dev Removes balance from total that is accounted for elsewhere (e.g. product-level accumulators)\n * @param self The struct to operate on\n * @param amount Amount of collateral to debit\n */\n function debit(OptimisticLedger storage self, UFixed18 amount) internal {\n self.total = self.total.sub(amount);\n }\n\n /**\n * @notice Reduces the amount of collateral shortfall in the ledger\n * @param self The struct to operate on\n * @param amount Amount of shortfall to resolve\n */\n function resolve(OptimisticLedger storage self, UFixed18 amount) internal {\n self.shortfall = self.shortfall.sub(amount);\n self.total = self.total.add(amount);\n }\n}\n" + }, + "contracts/controller/Controller.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol\";\nimport \"../interfaces/IController.sol\";\nimport \"../interfaces/ICollateral.sol\";\nimport \"../interfaces/IIncentivizer.sol\";\nimport \"../interfaces/IProduct.sol\";\n\n/**\n * @title Controller\n * @notice Manages creating new products and global protocol parameters.\n */\ncontract Controller is IController, UInitializable {\n /// @dev Collateral contract address for the protocol\n AddressStorage private constant _collateral = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.collateral\"));\n function collateral() public view returns (ICollateral) { return ICollateral(_collateral.read()); }\n\n /// @dev Incentivizer contract address for the protocol\n AddressStorage private constant _incentivizer = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.incentivizer\"));\n function incentivizer() public view returns (IIncentivizer) { return IIncentivizer(_incentivizer.read()); }\n\n /// @dev Product implementation beacon address for the protocol\n AddressStorage private constant _productBeacon = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.productBeacon\"));\n function productBeacon() public view returns (IBeacon) { return IBeacon(_productBeacon.read()); }\n\n /// @dev MultiInvoker contract address for the protocol\n AddressStorage private constant _multiInvoker = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.multiInvoker\"));\n function multiInvoker() public view returns (IMultiInvoker) { return IMultiInvoker(_multiInvoker.read()); }\n\n /// @dev Percent of collected fees that go to the protocol treasury vs the product treasury\n UFixed18Storage private constant _protocolFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.protocolFee\"));\n function protocolFee() public view returns (UFixed18) { return _protocolFee.read(); }\n\n /// @dev Minimum allowable funding fee for a product\n UFixed18Storage private constant _minFundingFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.minFundingFee\"));\n function minFundingFee() public view returns (UFixed18) { return _minFundingFee.read(); }\n\n /// @dev Fee on maintenance for liquidation\n UFixed18Storage private constant _liquidationFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.liquidationFee\"));\n function liquidationFee() public view returns (UFixed18) { return _liquidationFee.read(); }\n\n /// @dev Fee on incentivization programs\n UFixed18Storage private constant _incentivizationFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.incentivizationFee\"));\n function incentivizationFee() public view returns (UFixed18) { return _incentivizationFee.read(); }\n\n /// @dev Minimum allowable collateral amount per user account\n UFixed18Storage private constant _minCollateral = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.Controller.minCollateral\"));\n function minCollateral() public view returns (UFixed18) { return _minCollateral.read(); }\n\n /// @dev Maximum incentivization programs per product allowed\n Uint256Storage private constant _programsPerProduct = Uint256Storage.wrap(keccak256(\"equilibria.perennial.Controller.programsPerProduct\"));\n function programsPerProduct() public view returns (uint256) { return _programsPerProduct.read(); }\n\n /// @dev Protocol pauser address. address(0) defaults to owner(0)\n AddressStorage private constant _pauser = AddressStorage.wrap(keccak256(\"equilibria.perennial.Controller.pauser\"));\n function pauser() public view returns (address) {\n address pauser_ = _pauser.read();\n return pauser_ == address(0) ? owner() : pauser_;\n }\n\n /// @dev The paused status of the protocol\n BoolStorage private constant _paused = BoolStorage.wrap(keccak256(\"equilibria.perennial.Controller.paused\"));\n function paused() public view returns (bool) { return _paused.read(); }\n\n /// @dev List of product coordinators\n Coordinator[] private _coordinators;\n\n /// @dev Mapping of the coordinator for each product\n mapping(IProduct => uint256) public coordinatorFor;\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n * @param collateral_ Collateral contract address\n * @param incentivizer_ Incentivizer contract address\n * @param productBeacon_ Product implementation beacon address\n */\n function initialize(\n ICollateral collateral_,\n IIncentivizer incentivizer_,\n IBeacon productBeacon_\n ) external initializer(1) {\n _createCoordinator();\n\n updateCollateral(collateral_);\n updateIncentivizer(incentivizer_);\n updateProductBeacon(productBeacon_);\n }\n\n /**\n * @notice Creates a new coordinator with `msg.sender` as the owner\n * @return New coordinator ID\n */\n function createCoordinator() external returns (uint256) {\n return _createCoordinator();\n }\n\n /**\n * @notice Creates a new coordinator with `msg.sender` as the owner\n * @dev `treasury` and `pauser` initialize as the 0-address, defaulting to the `owner`\n * @return New coordinator ID\n */\n function _createCoordinator() private returns (uint256) {\n uint256 coordinatorId = _coordinators.length;\n\n _coordinators.push(Coordinator({\n pendingOwner: address(0),\n owner: msg.sender,\n treasury: address(0)\n }));\n\n emit CoordinatorCreated(coordinatorId, msg.sender);\n\n return coordinatorId;\n }\n\n /**\n * @notice Updates the pending owner of an existing coordinator\n * @dev Must be called by the coordinator's current owner\n * @param coordinatorId Coordinator to update\n * @param newPendingOwner New pending owner address\n */\n function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external onlyOwner(coordinatorId) {\n _coordinators[coordinatorId].pendingOwner = newPendingOwner;\n emit CoordinatorPendingOwnerUpdated(coordinatorId, newPendingOwner);\n }\n\n /**\n * @notice Accepts ownership over an existing coordinator\n * @dev Must be called by the coordinator's pending owner\n * @param coordinatorId Coordinator to update\n */\n function acceptCoordinatorOwner(uint256 coordinatorId) external {\n Coordinator storage coordinator = _coordinators[coordinatorId];\n address newPendingOwner = coordinator.pendingOwner;\n\n if (msg.sender != newPendingOwner) revert ControllerNotPendingOwnerError(coordinatorId);\n\n coordinator.pendingOwner = address(0);\n coordinator.owner = newPendingOwner;\n emit CoordinatorOwnerUpdated(coordinatorId, newPendingOwner);\n }\n\n /**\n * @notice Updates the treasury of an existing coordinator\n * @dev Must be called by the coordinator's current owner. Defaults to the coordinator `owner` if set to address(0)\n * @param coordinatorId Coordinator to update\n * @param newTreasury New treasury address\n */\n function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external onlyOwner(coordinatorId) {\n _coordinators[coordinatorId].treasury = newTreasury;\n emit CoordinatorTreasuryUpdated(coordinatorId, newTreasury);\n }\n\n /**\n * @notice Creates a new product market with `provider`\n * @dev Can only be called by the coordinator owner\n * @param coordinatorId Coordinator that will own the product\n * @param productInfo Product params used to initialize the product\n * @return New product contract address\n */\n function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo)\n external onlyOwner(coordinatorId) returns (IProduct) {\n if (coordinatorId == 0) revert ControllerNoZeroCoordinatorError();\n\n BeaconProxy newProductProxy = new BeaconProxy(address(productBeacon()), abi.encodeCall(IProduct.initialize, productInfo));\n IProduct newProduct = IProduct(address(newProductProxy));\n coordinatorFor[newProduct] = coordinatorId;\n emit ProductCreated(newProduct, productInfo);\n\n return newProduct;\n }\n\n /**\n * @notice Updates the Collateral contract address\n * @param newCollateral New Collateral contract address\n */\n function updateCollateral(ICollateral newCollateral) public onlyOwner(0) {\n if (!Address.isContract(address(newCollateral))) revert ControllerNotContractAddressError();\n _collateral.store(address(newCollateral));\n emit CollateralUpdated(newCollateral);\n }\n\n /**\n * @notice Updates the Incentivizer contract address\n * @param newIncentivizer New Incentivizer contract address\n */\n function updateIncentivizer(IIncentivizer newIncentivizer) public onlyOwner(0) {\n if (!Address.isContract(address(newIncentivizer))) revert ControllerNotContractAddressError();\n _incentivizer.store(address(newIncentivizer));\n emit IncentivizerUpdated(newIncentivizer);\n }\n\n /**\n * @notice Updates the Product implementation beacon address\n * @param newProductBeacon New Product implementation beacon address\n */\n function updateProductBeacon(IBeacon newProductBeacon) public onlyOwner(0) {\n if (!Address.isContract(address(newProductBeacon))) revert ControllerNotContractAddressError();\n _productBeacon.store(address(newProductBeacon));\n emit ProductBeaconUpdated(newProductBeacon);\n }\n\n /**\n * @notice Updates the MultiInvoker contract address\n * @param newMultiInvoker New MultiInvoker contract address\n */\n function updateMultiInvoker(IMultiInvoker newMultiInvoker) public onlyOwner(0) {\n if (!Address.isContract(address(newMultiInvoker))) revert ControllerNotContractAddressError();\n _multiInvoker.store(address(newMultiInvoker));\n emit MultiInvokerUpdated(newMultiInvoker);\n }\n\n /**\n * @notice Updates the protocol-product fee split\n * @param newProtocolFee New protocol-product fee split\n */\n function updateProtocolFee(UFixed18 newProtocolFee) public onlyOwner(0) {\n if (newProtocolFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidProtocolFeeError();\n\n _protocolFee.store(newProtocolFee);\n emit ProtocolFeeUpdated(newProtocolFee);\n }\n\n /**\n * @notice Updates the minimum allowed funding fee\n * @param newMinFundingFee New minimum allowed funding fee\n */\n function updateMinFundingFee(UFixed18 newMinFundingFee) public onlyOwner(0) {\n if (newMinFundingFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidMinFundingFeeError();\n\n _minFundingFee.store(newMinFundingFee);\n emit MinFundingFeeUpdated(newMinFundingFee);\n }\n\n /**\n * @notice Updates the liquidation fee\n * @param newLiquidationFee New liquidation fee\n */\n function updateLiquidationFee(UFixed18 newLiquidationFee) public onlyOwner(0) {\n if (newLiquidationFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidLiquidationFeeError();\n\n _liquidationFee.store(newLiquidationFee);\n emit LiquidationFeeUpdated(newLiquidationFee);\n }\n\n /**\n * @notice Updates the incentivization fee\n * @param newIncentivizationFee New incentivization fee\n */\n function updateIncentivizationFee(UFixed18 newIncentivizationFee) public onlyOwner(0) {\n if (newIncentivizationFee.gt(UFixed18Lib.ONE)) revert ControllerInvalidIncentivizationFeeError();\n\n _incentivizationFee.store(newIncentivizationFee);\n emit IncentivizationFeeUpdated(newIncentivizationFee);\n }\n\n /**\n * @notice Updates the minimum allowed collateral amount per user account\n * @param newMinCollateral New minimum allowed collateral amount\n */\n function updateMinCollateral(UFixed18 newMinCollateral) public onlyOwner(0) {\n _minCollateral.store(newMinCollateral);\n emit MinCollateralUpdated(newMinCollateral);\n }\n\n /**\n * @notice Updates the maximum incentivization programs per product allowed\n * @param newProgramsPerProduct New maximum incentivization programs per product allowed\n */\n function updateProgramsPerProduct(uint256 newProgramsPerProduct) public onlyOwner(0) {\n _programsPerProduct.store(newProgramsPerProduct);\n emit ProgramsPerProductUpdated(newProgramsPerProduct);\n }\n\n /**\n * @notice Updates the protocol pauser address. Zero address defaults to owner(0)\n * @param newPauser New protocol pauser address\n */\n function updatePauser(address newPauser) public onlyOwner(0) {\n _pauser.store(newPauser);\n emit PauserUpdated(newPauser);\n }\n\n /**\n * @notice Updates the protocol paused state\n * @param newPaused New protocol paused state\n */\n function updatePaused(bool newPaused) public onlyPauser {\n _paused.store(newPaused);\n emit PausedUpdated(newPaused);\n }\n\n /**\n * @notice Returns whether a contract is a product\n * @param product Contract address to check\n * @return Whether a contract is a product\n */\n function isProduct(IProduct product) external view returns (bool) {\n return coordinatorFor[product] != 0;\n }\n\n /**\n * @notice Returns coordinator state for coordinator `coordinatorId`\n * @param coordinatorId Coordinator to return for\n * @return Coordinator state\n */\n function coordinators(uint256 coordinatorId) external view returns (Coordinator memory) {\n return _coordinators[coordinatorId];\n }\n\n /**\n * @notice Returns the pending owner of the protocol\n * @return Owner of the protocol\n */\n function pendingOwner() public view returns (address) {\n return pendingOwner(0);\n }\n\n /**\n * @notice Returns the pending owner of the coordinator `coordinatorId`\n * @param coordinatorId Coordinator to return for\n * @return Pending owner of the coordinator\n */\n function pendingOwner(uint256 coordinatorId) public view returns (address) {\n return _coordinators[coordinatorId].pendingOwner;\n }\n\n /**\n * @notice Returns the owner of the protocol\n * @return Owner of the protocol\n */\n function owner() public view returns (address) {\n return owner(0);\n }\n\n /**\n * @notice Returns the owner of the coordinator `coordinatorId`\n * @param coordinatorId Coordinator to return for\n * @return Owner of the coordinator\n */\n function owner(uint256 coordinatorId) public view returns (address) {\n return _coordinators[coordinatorId].owner;\n }\n\n /**\n * @notice Returns the owner of the product `product`\n * @param product Product to return for\n * @return Owner of the product\n */\n function owner(IProduct product) external view returns (address) {\n return owner(coordinatorFor[product]);\n }\n\n /**\n * @notice Returns the treasury of the protocol\n * @dev Defaults to the `owner` when `treasury` is unset\n * @return Treasury of the protocol\n */\n function treasury() external view returns (address) {\n return treasury(0);\n }\n\n /**\n * @notice Returns the treasury of the coordinator `coordinatorId`\n * @dev Defaults to the `owner` when `treasury` is unset\n * @param coordinatorId Coordinator to return for\n * @return Treasury of the coordinator\n */\n function treasury(uint256 coordinatorId) public view returns (address) {\n address _treasury = _coordinators[coordinatorId].treasury;\n return _treasury == address(0) ? owner(coordinatorId) : _treasury;\n }\n\n /**\n * @notice Returns the treasury of the product `product`\n * @dev Defaults to the `owner` when `treasury` is unset\n * @param product Product to return for\n * @return Treasury of the product\n */\n function treasury(IProduct product) external view returns (address) {\n return treasury(coordinatorFor[product]);\n }\n\n /// @dev Only allow owner of `coordinatorId` to call\n modifier onlyOwner(uint256 coordinatorId) {\n if (msg.sender != owner(coordinatorId)) revert ControllerNotOwnerError(coordinatorId);\n\n _;\n }\n\n /// @dev Only allow the pauser to call\n modifier onlyPauser {\n if (msg.sender != pauser()) revert ControllerNotPauserError();\n\n _;\n }\n}\n" + }, + "contracts/controller/UControllerProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/root/storage/UStorage.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../interfaces/IController.sol\";\nimport \"../interfaces/IProduct.sol\";\n\n/**\n * @title UControllerProvider\n * @notice Mix-in that manages a controller pointer and associated permissioning modifiers.\n * @dev Uses unstructured storage so that it is safe to mix-in to upgreadable contracts without modifying\n * their storage layout.\n */\nabstract contract UControllerProvider is UInitializable {\n error NotOwnerError(uint256 coordinatorId);\n error NotProductError(IProduct product);\n error NotCollateralError();\n error PausedError();\n error InvalidControllerError();\n error NotAccountOrMultiInvokerError(address account, address operator);\n\n /// @dev The controller contract address\n AddressStorage private constant _controller = AddressStorage.wrap(keccak256(\"equilibria.perennial.UControllerProvider.controller\"));\n function controller() public view returns (IController) { return IController(_controller.read()); }\n\n /**\n * @notice Initializes the contract state\n * @param controller_ Protocol Controller contract address\n */\n // solhint-disable-next-line func-name-mixedcase\n function __UControllerProvider__initialize(IController controller_) internal onlyInitializer {\n if (!Address.isContract(address(controller_))) revert InvalidControllerError();\n _controller.store(address(controller_));\n }\n\n /// @dev Only allow a valid product contract to call\n modifier onlyProduct {\n if (!controller().isProduct(IProduct(msg.sender))) revert NotProductError(IProduct(msg.sender));\n\n _;\n }\n\n /// @dev Verify that `product` is a valid product contract\n modifier isProduct(IProduct product) {\n if (!controller().isProduct(product)) revert NotProductError(product);\n\n _;\n }\n\n /// @dev Only allow the Collateral contract to call\n modifier onlyCollateral {\n if (msg.sender != address(controller().collateral())) revert NotCollateralError();\n\n _;\n }\n\n /// @dev Only allow the coordinator owner to call\n modifier onlyOwner(uint256 coordinatorId) {\n if (msg.sender != controller().owner(coordinatorId)) revert NotOwnerError(coordinatorId);\n\n _;\n }\n\n /// @dev Only allow if the protocol is currently unpaused\n modifier notPaused() {\n if (controller().paused()) revert PausedError();\n\n _;\n }\n\n /// @dev Ensure the `msg.sender` is ether the `account` or the Controller's multiInvoker\n modifier onlyAccountOrMultiInvoker(address account) {\n if (!(msg.sender == account || msg.sender == address(controller().multiInvoker()))) {\n revert NotAccountOrMultiInvokerError(account, msg.sender);\n }\n _;\n }\n}\n" + }, + "contracts/forwarder/Forwarder.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"../interfaces/IForwarder.sol\";\n\n/**\n * @title Forwarder\n * @notice Facilitates collateral deposits to the protocol where the amount is supplied\n * in USDC then wrapped as DSU before being deposited.\n */\ncontract Forwarder is IForwarder {\n // @dev USDC stablecoin\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n // @dev DSU stablecoin\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n\n /// @dev Contract that wraps USDC to DSU\n IBatcher public immutable batcher;\n\n /// @dev Contract managing state for collateral accounts in the protocol\n ICollateral public immutable collateral;\n\n /**\n * @notice Initializes the contract state\n * @param usdc_ The USDC token contract address\n * @param dsu_ The DSU token contract address\n * @param batcher_ The USDC-to-DSU batcher contract address\n * @param collateral_ The perennial collateral contract address\n */\n constructor(\n Token6 usdc_,\n Token18 dsu_,\n IBatcher batcher_,\n ICollateral collateral_\n ) {\n if (!Address.isContract(Token6.unwrap(usdc_))) revert ForwarderNotContractAddressError();\n if (!Address.isContract(Token18.unwrap(dsu_))) revert ForwarderNotContractAddressError();\n if (!Address.isContract(address(batcher_))) revert ForwarderNotContractAddressError();\n if (!Address.isContract(address(collateral_))) revert ForwarderNotContractAddressError();\n\n USDC = usdc_;\n DSU = dsu_;\n batcher = batcher_;\n collateral = collateral_;\n\n USDC.approve(address(batcher));\n DSU.approve(address(collateral));\n }\n\n /**\n * @notice Pulls `amount` of USDC from `msg.sender`'s balance, wraps it as DSU,\n and deposits it as collateral to `account`'s `product` account\n * @param account Account to deposit the collateral for\n * @param product Product to credit the collateral to\n * @param amount 18 decimals-normalized stablecoin (USDC, DSU) value of collateral to deposit\n */\n function wrapAndDeposit(\n address account,\n IProduct product,\n UFixed18 amount\n ) external {\n USDC.pull(msg.sender, amount, true);\n batcher.wrap(amount, address(this));\n collateral.depositTo(account, product, amount);\n emit WrapAndDeposit(account, product, amount);\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/emptyset-batcher/batcher/Batcher.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/emptyset-batcher/batcher/Batcher.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Arbitrum.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Arbitrum.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Optimism.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@equilibria/root/control/unstructured/CrossChainOwner/UCrossChainOwner_Optimism.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/governance/TimelockController.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/governance/TimelockController.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol';\n" + }, + "contracts/incentivizer/Incentivizer.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/root/control/unstructured/UReentrancyGuard.sol\";\nimport \"../interfaces/IIncentivizer.sol\";\nimport \"../interfaces/IController.sol\";\nimport \"../controller/UControllerProvider.sol\";\nimport \"./types/ProductManager.sol\";\n\n/**\n * @title Incentivizer\n * @notice Manages logic and state for all incentive programs in the protocol.\n */\ncontract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, UReentrancyGuard {\n /// @dev Product management state\n mapping(IProduct => ProductManager) private _products;\n\n /// @dev Fees that have been collected, but remain unclaimed\n mapping(Token18 => UFixed18) public fees;\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n * @param controller_ Factory contract address\n */\n function initialize(IController controller_) external initializer(1) {\n __UControllerProvider__initialize(controller_);\n __UReentrancyGuard__initialize();\n }\n\n /**\n * @notice Creates a new incentive program\n * @dev Must be called as the product or protocol owner\n * @param product The product to create the new program on\n * @param programInfo Parameters for the new program\n * @return programId New program's ID\n */\n function create(IProduct product, ProgramInfo calldata programInfo)\n external\n nonReentrant\n isProduct(product)\n notPaused\n onlyOwner(programInfo.coordinatorId)\n returns (uint256 programId) {\n IController _controller = controller();\n\n // Validate\n if (programInfo.coordinatorId != 0 && programInfo.coordinatorId != _controller.coordinatorFor(product))\n revert IncentivizerNotAllowedError(product);\n if (active(product) >= _controller.programsPerProduct())\n revert IncentivizerTooManyProgramsError();\n ProgramInfoLib.validate(programInfo);\n\n // Take fee\n (ProgramInfo memory newProgramInfo, UFixed18 programFeeAmount) = ProgramInfoLib.deductFee(programInfo, _controller.incentivizationFee());\n fees[newProgramInfo.token] = fees[newProgramInfo.token].add(programFeeAmount);\n\n // Register program\n programId = _products[product].register(newProgramInfo);\n\n // Charge creator\n newProgramInfo.token.pull(msg.sender, programInfo.amount.sum());\n\n emit ProgramCreated(\n product,\n programId,\n newProgramInfo,\n programFeeAmount\n );\n }\n\n /**\n * @notice Completes an in-progress program early\n * @dev Must be called as the program owner\n * @param product Product that the program is running on\n * @param programId Program to complete early\n */\n function complete(IProduct product, uint256 programId)\n external\n nonReentrant\n isProgram(product, programId)\n notPaused\n onlyProgramOwner(product, programId)\n {\n ProductManagerLib.SyncResult memory syncResult = _products[product].complete(product, programId);\n _handleSyncResult(product, syncResult);\n }\n\n /**\n * @notice Starts and completes programs as they become available\n * @dev Called every settle() from each product\n * @param currentOracleVersion The preloaded current oracle version\n */\n function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external onlyProduct {\n IProduct product = IProduct(msg.sender);\n\n ProductManagerLib.SyncResult[] memory syncResults = _products[product].sync(product, currentOracleVersion);\n for (uint256 i = 0; i < syncResults.length; i++) {\n _handleSyncResult(product, syncResults[i]);\n }\n }\n\n /**\n * @notice Handles refunding and event emitting on program start and completion\n * @param product Product that the program is running on\n * @param syncResult The data from the sync event to handle\n */\n function _handleSyncResult(IProduct product, ProductManagerLib.SyncResult memory syncResult) private {\n uint256 programId = syncResult.programId;\n if (!syncResult.refundAmount.isZero())\n _products[product].token(programId).push(treasury(product, programId), syncResult.refundAmount);\n if (syncResult.versionStarted != 0)\n emit ProgramStarted(product, programId, syncResult.versionStarted);\n if (syncResult.versionComplete != 0)\n emit ProgramComplete(product, programId, syncResult.versionComplete);\n }\n\n /**\n * @notice Settles unsettled balance for `account`\n * @dev Called immediately proceeding a position update in the corresponding product\n * @param account Account to sync\n * @param currentOracleVersion The preloaded current oracle version\n */\n function syncAccount(\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) external onlyProduct {\n IProduct product = IProduct(msg.sender);\n _products[product].syncAccount(product, account, currentOracleVersion);\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for `product` programs\n * @param product Product to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function claim(IProduct product, uint256[] calldata programIds)\n external\n nonReentrant\n {\n _claimProduct(msg.sender, product, programIds);\n }\n\n /**\n * @notice Claims all of `account`'s rewards for `product` programs\n * @param account Account to claim rewards for\n * @param product Product to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function claimFor(address account, IProduct product, uint256[] calldata programIds)\n external\n nonReentrant\n onlyAccountOrMultiInvoker(account)\n {\n _claimProduct(account, product, programIds);\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for a specific program\n * @param products Products to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function claim(IProduct[] calldata products, uint256[][] calldata programIds)\n external\n nonReentrant\n {\n if (products.length != programIds.length) revert IncentivizerBatchClaimArgumentMismatchError();\n for (uint256 i; i < products.length; i++) {\n _claimProduct(msg.sender, products[i], programIds[i]);\n }\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for `product` programs\n * @dev Internal helper with validation checks\n * @param account Account to claim rewards for\n * @param product Product to claim rewards for\n * @param programIds Programs to claim rewards for\n */\n function _claimProduct(address account, IProduct product, uint256[] memory programIds)\n private\n isProduct(product)\n notPaused\n settleForAccount(account, product)\n {\n for (uint256 i; i < programIds.length; i++) {\n _claimProgram(account, product, programIds[i]);\n }\n }\n\n /**\n * @notice Claims all of `msg.sender`'s rewards for `programId` on `product`\n * @dev Internal helper with validation checks\n * @param account Account to claim rewards for\n * @param product Product to claim rewards for\n * @param programId Program to claim rewards for\n */\n function _claimProgram(address account, IProduct product, uint256 programId)\n private\n isProgram(product, programId)\n {\n ProductManager storage productManager = _products[product];\n UFixed18 claimAmount = productManager.claim(account, programId);\n productManager.token(programId).push(account, claimAmount);\n emit Claim(product, account, programId, claimAmount);\n }\n\n /**\n * @notice Claims all `tokens` fees to the protocol treasury\n * @param tokens Tokens to claim fees for\n */\n function claimFee(Token18[] calldata tokens) external notPaused {\n for(uint256 i; i < tokens.length; i++) {\n Token18 token = tokens[i];\n UFixed18 amount = fees[token];\n\n fees[token] = UFixed18Lib.ZERO;\n token.push(controller().treasury(), amount);\n\n emit FeeClaim(token, amount);\n }\n }\n\n /**\n * @notice Returns the quantity of active programs for a given product\n * @param product Product to check for\n * @return Number of active programs\n */\n function active(IProduct product) public view returns (uint256) {\n return _products[product].active();\n }\n\n /**\n * @notice Returns the quantity of programs for a given product\n * @param product Product to check for\n * @return Number of programs (inactive or active)\n */\n function count(IProduct product) external view returns (uint256) {\n return _products[product].programInfos.length;\n }\n\n /**\n * @notice Returns program info for program `programId`\n * @param product Product to return for\n * @param programId Program to return for\n * @return Program info\n */\n function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory) {\n return _products[product].programInfos[programId];\n }\n\n /**\n * @notice Returns `account`'s total unclaimed rewards for a specific program\n * @param product Product to return for\n * @param account Account to return for\n * @param programId Program to return for\n * @return `account`'s total unclaimed rewards for `programId`\n */\n function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18) {\n return _products[product].unclaimed(account, programId);\n }\n\n /**\n * @notice Returns available rewards for a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return Available rewards for `programId`\n */\n function available(IProduct product, uint256 programId) external view returns (UFixed18) {\n return _products[product].programs[programId].available;\n }\n\n /**\n * @notice Returns the version started for a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The version started for `programId`\n */\n function versionStarted(IProduct product, uint256 programId) external view returns (uint256) {\n return _products[product].programs[programId].versionStarted;\n }\n\n /**\n * @notice Returns the version completed for a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The version completed for `programId`\n */\n function versionComplete(IProduct product, uint256 programId) external view returns (uint256) {\n return _products[product].programs[programId].versionComplete;\n }\n\n /**\n * @notice Returns the owner of a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The owner of `programId`\n */\n function owner(IProduct product, uint256 programId) public view returns (address) {\n return controller().owner(_products[product].programInfos[programId].coordinatorId);\n }\n\n /**\n * @notice Returns the treasury of a specific program\n * @param product Product to return for\n * @param programId Program to return for\n * @return The treasury of `programId`\n */\n function treasury(IProduct product, uint256 programId) public view returns (address) {\n return controller().treasury(_products[product].programInfos[programId].coordinatorId);\n }\n\n /// @dev Helper to fully settle an account's state\n modifier settleForAccount(address account, IProduct product) {\n product.settleAccount(account);\n\n _;\n }\n\n /// @dev Only allow the owner of `programId` to call\n modifier onlyProgramOwner(IProduct product, uint256 programId) {\n if (msg.sender != owner(product, programId)) revert IncentivizerNotProgramOwnerError(product, programId);\n\n _;\n }\n\n /// @dev Only allow a valid `programId`\n modifier isProgram(IProduct product, uint256 programId) {\n if (!_products[product].valid(programId)) revert IncentivizerInvalidProgramError(product, programId);\n\n _;\n }\n}\n" + }, + "contracts/incentivizer/types/ProductManager.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport \"./Program.sol\";\n\n/// @dev ProductManager type\nstruct ProductManager {\n /// @dev Static program state\n ProgramInfo[] programInfos;\n\n /// @dev Dynamic program state\n mapping(uint256 => Program) programs;\n\n /// @dev Mapping of all active programs for each product\n EnumerableSet.UintSet activePrograms;\n\n /// @dev Mapping of all active programs for each user\n mapping(address => EnumerableSet.UintSet) activeProgramsFor;\n\n /// @dev Mapping of the next program to watch for for each user\n mapping(address => uint256) nextProgramFor;\n}\nusing ProductManagerLib for ProductManager global;\n\n/**\n * @title ProductManagerLib\n * @notice Library that manages each product's incentivization state and logic.\n */\nlibrary ProductManagerLib {\n using EnumerableSet for EnumerableSet.UintSet;\n\n /// @dev Result data for a sync event\n struct SyncResult {\n /// @dev The programId that was updated\n uint256 programId;\n\n /// @dev If non-zero, the new versionStart value of the program\n uint256 versionStarted;\n\n /// @dev If non-zero, the new versionComplete value of the program\n uint256 versionComplete;\n\n /// @dev If non-zero, the amount to refund due to completion\n UFixed18 refundAmount;\n }\n\n /**\n * @notice Registers a new program on this product\n * @param self The Product manager to operate on\n * @param programInfo The static program info\n * @return programId The new program's ID\n */\n function register(\n ProductManager storage self,\n ProgramInfo memory programInfo\n ) internal returns (uint256 programId) {\n programId = self.programInfos.length;\n self.programInfos.push(programInfo);\n self.programs[programId].initialize(programInfo);\n self.activePrograms.add(programId);\n }\n\n /**\n * @notice Syncs this product with the latest data\n * @param self The Program manager to operate on\n * @param product This Product\n * @param currentOracleVersion The preloaded current oracle version\n */\n function sync(\n ProductManager storage self,\n IProduct product,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal returns (SyncResult[] memory results) {\n\n uint256[] memory activeProgramIds = self.activePrograms.values();\n results = new SyncResult[](activeProgramIds.length);\n\n for (uint256 i; i < activeProgramIds.length; i++) {\n // Load program\n uint256 programId = activeProgramIds[i];\n ProgramInfo memory programInfo = self.programInfos[programId];\n Program storage program = self.programs[programId];\n\n // If timestamp-started, grab current version (first version after start)\n uint256 versionStarted;\n if (program.versionStarted == 0 && programInfo.isStarted(currentOracleVersion.timestamp)) {\n versionStarted = _start(self, programId, currentOracleVersion);\n }\n\n // If timestamp-completed, grab previous version (last version before completion)\n uint256 versionComplete;\n UFixed18 refundAmount;\n if (program.versionComplete == 0 && programInfo.isComplete(currentOracleVersion.timestamp)) {\n (versionComplete, refundAmount) = _complete(self, product, programId);\n }\n\n // Save result\n results[i] = SyncResult(programId, versionStarted, versionComplete, refundAmount);\n }\n }\n\n /**\n * @notice Syncs an account for this product with the latest data\n * @dev Assumes that sync() has already been called as part of the transaction flow\n * @param self The Program manager to operate on\n * @param product This Product\n * @param account The account to sync\n * @param currentOracleVersion The preloaded current oracle version\n */\n function syncAccount(\n ProductManager storage self,\n IProduct product,\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal {\n\n // Add any unseen programs\n uint256 fromProgramId = self.nextProgramFor[account];\n uint256 toProgramId = self.programInfos.length;\n for (uint256 programId = fromProgramId; programId < toProgramId; programId++) {\n self.activeProgramsFor[account].add(programId);\n }\n self.nextProgramFor[account] = toProgramId;\n\n // Settle programs\n uint256[] memory activeProgramIds = self.activeProgramsFor[account].values();\n for (uint256 i; i < activeProgramIds.length; i++) {\n uint256 programId = activeProgramIds[i];\n Program storage program = self.programs[programId];\n program.settle(product, self.programInfos[programId], account, currentOracleVersion);\n if (!self.activePrograms.contains(programId) && currentOracleVersion.version >= program.versionComplete) {\n self.activeProgramsFor[account].remove(programId);\n }\n }\n }\n\n /**\n * @notice Returns the quantity of active programs for this product\n * @param self The Program manager to operate on\n * @return The quantity of active programs\n */\n function active(ProductManager storage self) internal view returns (uint256) {\n return self.activePrograms.length();\n }\n\n /**\n * @notice Forces the specified program to complete if it hasn't already\n * @param self The Program manager to operate on\n * @param product The Product to operate on\n * @param programId The Program to complete\n * @return result The sync result data from completion\n */\n function complete(\n ProductManager storage self,\n IProduct product,\n uint256 programId\n ) internal returns (SyncResult memory result) {\n Program storage program = self.programs[programId];\n\n // If not started, start first\n if (program.versionStarted == 0) {\n result.versionStarted = _start(self, programId, product.currentVersion());\n }\n\n // If not completed already, complete\n if (program.versionComplete == 0) {\n (result.versionComplete, result.refundAmount) = _complete(self, product, programId);\n }\n }\n\n /**\n * @notice Starts the program\n * @dev Rewards do not start accruing until the program has started\n * Internal helper, does not prevent incorrectly-timed starting\n * @param self The Program manager to operate on\n * @param programId The Program to start\n * @param currentOracleVersion The effective starting oracle version\n * @return versionStarted The version that the program started\n */\n function _start(\n ProductManager storage self,\n uint256 programId,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal returns (uint256 versionStarted) {\n versionStarted = currentOracleVersion.version;\n self.programs[programId].start(currentOracleVersion.version);\n }\n\n /**\n * @notice Completes the program\n * @dev Completion stops rewards from accruing\n * Internal helper, does not prevent incorrectly-timed completion\n * @param self The Program manager to operate on\n * @param product The Product to operate on\n * @param programId The Program to complete\n * @return versionComplete The version that the program complete\n * @return refundAmount The refunded token amount\n */\n function _complete(\n ProductManager storage self,\n IProduct product,\n uint256 programId\n ) internal returns (uint256 versionComplete, UFixed18 refundAmount) {\n (versionComplete, refundAmount) = self.programs[programId].complete(product, self.programInfos[programId]);\n self.activePrograms.remove(programId);\n }\n\n /**\n * @notice Claims all of `account`'s rewards for a specific program\n * @param self The Program manager to operate on\n * @param account Account to claim rewards for\n * @param programId Program to claim rewards for\n * @return Amount claimed\n */\n function claim(ProductManager storage self, address account, uint256 programId) internal returns (UFixed18) {\n return self.programs[programId].claim(account);\n }\n\n /**\n * @notice Returns the total amount of unclaimed rewards for account `account`\n * @param self The Program manager to operate on\n * @param account The account to check for\n * @param programId The Program to check for\n * @return Total amount of unclaimed rewards for account\n */\n function unclaimed(ProductManager storage self, address account, uint256 programId) internal view returns (UFixed18) {\n if (!valid(self, programId)) return (UFixed18Lib.ZERO);\n return self.programs[programId].settled[account];\n }\n\n /**\n * @notice Returns the token denominatino of the program's rewards\n * @param self The Program manager to operate on\n * @param programId The Program to check for\n * @return The token for the program\n */\n function token(ProductManager storage self, uint256 programId) internal view returns (Token18) {\n return self.programInfos[programId].token;\n }\n\n /**\n * @notice Returns whether the supplied programId is valid\n * @param self The Program manager to operate on\n * @param programId The Program to check for\n * @return Whether the supplied programId is valid\n */\n function valid(ProductManager storage self, uint256 programId) internal view returns (bool) {\n return programId < self.programInfos.length;\n }\n}\n" + }, + "contracts/incentivizer/types/Program.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../interfaces/types/ProgramInfo.sol\";\n\n/// @dev Program type\nstruct Program {\n /// @dev Mapping of latest rewards settled for each account\n mapping(address => UFixed18) settled;\n\n /// @dev Total amount of rewards yet to be claimed\n UFixed18 available;\n\n /// @dev Oracle version that the program started, 0 when hasn't started\n uint256 versionStarted;\n\n /// @dev Oracle version that the program completed, 0 is still ongoing\n uint256 versionComplete;\n}\nusing ProgramLib for Program global;\n\n/**\n * @title ProgramLib\n * @notice Library that manages all of the mutable state for a single incentivization program.\n */\nlibrary ProgramLib {\n /**\n * @notice Initializes the program state\n * @param self The Program to operate on\n * @param programInfo Static program information\n */\n function initialize(Program storage self, ProgramInfo memory programInfo) internal {\n self.available = programInfo.amount.sum();\n }\n\n /**\n * @notice Starts the program\n * @dev Rewards do not start accruing until the program has started accruing\n * Does not stop double-starting\n * @param self The Program to operate on\n * @param oracleVersion The effective starting oracle version\n */\n function start(Program storage self, uint256 oracleVersion) internal {\n self.versionStarted = oracleVersion;\n }\n\n /**\n * @notice Completes the program\n * @dev Completion stops rewards from accruing\n * Does not prevent double-completion\n * @param self The Program to operate on\n * @param product The Product to operate on\n * @param programInfo Static program information\n * @return versionComplete The version that the program completed on\n * @return refundAmount The refund amount from the program\n */\n function complete(\n Program storage self,\n IProduct product,\n ProgramInfo memory programInfo\n ) internal returns (uint256 versionComplete, UFixed18 refundAmount) {\n uint256 versionStarted = self.versionStarted;\n versionComplete = Math.max(versionStarted, product.latestVersion());\n self.versionComplete = versionComplete;\n\n IOracleProvider.OracleVersion memory fromOracleVersion = product.atVersion(versionStarted);\n IOracleProvider.OracleVersion memory toOracleVersion = product.atVersion(versionComplete);\n\n uint256 inactiveDuration = programInfo.duration - (toOracleVersion.timestamp - fromOracleVersion.timestamp);\n refundAmount = programInfo.amount.sum().muldiv(inactiveDuration, programInfo.duration);\n self.available = self.available.sub(refundAmount);\n }\n\n /**\n * @notice Settles unclaimed rewards for account `account`\n * @param self The Program to operate on\n * @param product The Product to operate on\n * @param programInfo Static program information\n * @param account The account to settle for\n * @param currentOracleVersion The preloaded current oracle version\n */\n function settle(\n Program storage self,\n IProduct product,\n ProgramInfo memory programInfo,\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) internal {\n UFixed18 unsettledAmount = _unsettled(self, product, programInfo, account, currentOracleVersion);\n self.settled[account] = self.settled[account].add(unsettledAmount);\n self.available = self.available.sub(unsettledAmount);\n }\n\n /**\n * @notice Claims settled rewards for account `account`\n * @param self The Program to operate on\n * @param account The account to claim for\n */\n function claim(Program storage self, address account) internal returns (UFixed18 claimedAmount) {\n claimedAmount = self.settled[account];\n self.settled[account] = UFixed18Lib.ZERO;\n }\n\n /**\n * @notice Returns the unsettled amount of unclaimed rewards for account `account`\n * @dev Clears when a program is closed\n * Assumes that position is unchanged since last settlement, must be settled prior to user position update\n * @param self The Program to operate on\n * @param product The Product to operate on\n * @param programInfo Static program information\n * @param account The account to claim for\n * @param currentOracleVersion Current oracle version\n * @return amount Amount of unsettled rewards for account\n */\n function _unsettled(\n Program storage self,\n IProduct product,\n ProgramInfo memory programInfo,\n address account,\n IOracleProvider.OracleVersion memory currentOracleVersion\n ) private view returns (UFixed18 amount) {\n // program stage overview\n //\n // V = latest user settle version, V' = current user settle version\n // S = versionStarted, E = versionEnded\n //\n // (1) V V' S E program not yet started\n // (2) V S V' E use versionStarted -> V' for userShareDelta\n // (3) S V V' E use V -> V' for userShareDelta\n // (4) S V E V' use V -> versionComplete for userShareDelta\n // (5) S E V V' program already completed\n // (6) V S E V' use versionStarted -> versionComplete for userShareDelta\n //\n // NOTE: V == S and V' == E both default to the inner case\n\n (uint256 _versionStarted, uint256 _versionComplete) = (\n self.versionStarted == 0 ? currentOracleVersion.version : self.versionStarted, // start must be no earlier than current version\n self.versionComplete == 0 ? type(uint256).max : self.versionComplete // we don't know when completion occurs\n );\n\n // accruing must start between self.versionStarted and self.versionComplete\n uint256 fromVersion = Math.min(_versionComplete, Math.max(_versionStarted, product.latestVersion(account)));\n // accruing must complete between self.versionStarted and self.versionComplete, we know self.versionStarted must be no earlier than current version\n uint256 toVersion = Math.min(_versionComplete, currentOracleVersion.version);\n\n Accumulator memory globalShareDelta = product.shareAtVersion(toVersion).sub(product.shareAtVersion(fromVersion));\n Accumulator memory computedUserShareDelta = product.position(account).mul(globalShareDelta);\n amount = UFixed18Lib.from(programInfo.amountPerShare().mul(computedUserShareDelta).sum());\n }\n}\n" + }, + "contracts/interfaces/ICollateral.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/number/types/Fixed18.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"./IController.sol\";\nimport \"./IProduct.sol\";\n\ninterface ICollateral {\n event Deposit(address indexed user, IProduct indexed product, UFixed18 amount);\n event Withdrawal(address indexed user, IProduct indexed product, UFixed18 amount);\n event AccountSettle(IProduct indexed product, address indexed account, Fixed18 amount, UFixed18 newShortfall);\n event ProductSettle(IProduct indexed product, UFixed18 protocolFee, UFixed18 productFee);\n event Liquidation(address indexed user, IProduct indexed product, address liquidator, UFixed18 fee);\n event ShortfallResolution(IProduct indexed product, UFixed18 amount);\n event FeeClaim(address indexed account, UFixed18 amount);\n\n error CollateralCantLiquidate(UFixed18 totalMaintenance, UFixed18 totalCollateral);\n error CollateralInsufficientCollateralError();\n error CollateralUnderLimitError();\n error CollateralZeroAddressError();\n error CollateralAccountLiquidatingError(address account);\n\n function token() external view returns (Token18);\n function fees(address account) external view returns (UFixed18);\n function initialize(IController controller_) external;\n function depositTo(address account, IProduct product, UFixed18 amount) external;\n function withdrawTo(address receiver, IProduct product, UFixed18 amount) external;\n function withdrawFrom(address account, address receiver, IProduct product, UFixed18 amount) external;\n function liquidate(address account, IProduct product) external;\n function settleAccount(address account, Fixed18 amount) external;\n function settleProduct(UFixed18 amount) external;\n function collateral(address account, IProduct product) external view returns (UFixed18);\n function collateral(IProduct product) external view returns (UFixed18);\n function shortfall(IProduct product) external view returns (UFixed18);\n function liquidatable(address account, IProduct product) external view returns (bool);\n function liquidatableNext(address account, IProduct product) external view returns (bool);\n function resolveShortfall(IProduct product, UFixed18 amount) external;\n function claimFee() external;\n}\n" + }, + "contracts/interfaces/IContractPayoffProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\n\ninterface IContractPayoffProvider {\n function payoff(Fixed18 price) external view returns (Fixed18 payoff);\n}\n" + }, + "contracts/interfaces/IController.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\";\nimport \"./ICollateral.sol\";\nimport \"./IIncentivizer.sol\";\nimport \"./IProduct.sol\";\nimport \"./IMultiInvoker.sol\";\nimport \"./types/PayoffDefinition.sol\";\n\ninterface IController {\n /// @dev Coordinator of a one or many products\n struct Coordinator {\n /// @dev Pending owner of the product, can accept ownership\n address pendingOwner;\n\n /// @dev Owner of the product, allowed to update select parameters\n address owner;\n\n /// @dev Treasury of the product, collects fees\n address treasury;\n }\n\n event CollateralUpdated(ICollateral newCollateral);\n event IncentivizerUpdated(IIncentivizer newIncentivizer);\n event ProductBeaconUpdated(IBeacon newProductBeacon);\n event MultiInvokerUpdated(IMultiInvoker newMultiInvoker);\n event ProtocolFeeUpdated(UFixed18 newProtocolFee);\n event MinFundingFeeUpdated(UFixed18 newMinFundingFee);\n event LiquidationFeeUpdated(UFixed18 newLiquidationFee);\n event IncentivizationFeeUpdated(UFixed18 newIncentivizationFee);\n event MinCollateralUpdated(UFixed18 newMinCollateral);\n event ProgramsPerProductUpdated(uint256 newProgramsPerProduct);\n event PauserUpdated(address newPauser);\n event PausedUpdated(bool newPaused);\n event CoordinatorPendingOwnerUpdated(uint256 indexed coordinatorId, address newPendingOwner);\n event CoordinatorOwnerUpdated(uint256 indexed coordinatorId, address newOwner);\n event CoordinatorTreasuryUpdated(uint256 indexed coordinatorId, address newTreasury);\n event CoordinatorCreated(uint256 indexed coordinatorId, address owner);\n event ProductCreated(IProduct indexed product, IProduct.ProductInfo productInfo);\n\n error ControllerNoZeroCoordinatorError();\n error ControllerNotPauserError();\n error ControllerNotOwnerError(uint256 controllerId);\n error ControllerNotPendingOwnerError(uint256 controllerId);\n error ControllerInvalidProtocolFeeError();\n error ControllerInvalidMinFundingFeeError();\n error ControllerInvalidLiquidationFeeError();\n error ControllerInvalidIncentivizationFeeError();\n error ControllerNotContractAddressError();\n\n function collateral() external view returns (ICollateral);\n function incentivizer() external view returns (IIncentivizer);\n function productBeacon() external view returns (IBeacon);\n function multiInvoker() external view returns (IMultiInvoker);\n function coordinators(uint256 collateralId) external view returns (Coordinator memory);\n function coordinatorFor(IProduct product) external view returns (uint256);\n function protocolFee() external view returns (UFixed18);\n function minFundingFee() external view returns (UFixed18);\n function liquidationFee() external view returns (UFixed18);\n function incentivizationFee() external view returns (UFixed18);\n function minCollateral() external view returns (UFixed18);\n function programsPerProduct() external view returns (uint256);\n function pauser() external view returns (address);\n function paused() external view returns (bool);\n function initialize(ICollateral collateral_, IIncentivizer incentivizer_, IBeacon productBeacon_) external;\n function createCoordinator() external returns (uint256);\n function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external;\n function acceptCoordinatorOwner(uint256 coordinatorId) external;\n function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external;\n function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo) external returns (IProduct);\n function updateCollateral(ICollateral newCollateral) external;\n function updateIncentivizer(IIncentivizer newIncentivizer) external;\n function updateProductBeacon(IBeacon newProductBeacon) external;\n function updateMultiInvoker(IMultiInvoker newMultiInvoker) external;\n function updateProtocolFee(UFixed18 newProtocolFee) external;\n function updateMinFundingFee(UFixed18 newMinFundingFee) external;\n function updateLiquidationFee(UFixed18 newLiquidationFee) external;\n function updateIncentivizationFee(UFixed18 newIncentivizationFee) external;\n function updateMinCollateral(UFixed18 newMinCollateral) external;\n function updateProgramsPerProduct(uint256 newProductsPerProduct) external;\n function updatePauser(address newPauser) external;\n function updatePaused(bool newPaused) external;\n function isProduct(IProduct product) external view returns (bool);\n function owner() external view returns (address);\n function owner(uint256 coordinatorId) external view returns (address);\n function owner(IProduct product) external view returns (address);\n function treasury() external view returns (address);\n function treasury(uint256 coordinatorId) external view returns (address);\n function treasury(IProduct product) external view returns (address);\n}\n" + }, + "contracts/interfaces/IForwarder.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"./ICollateral.sol\";\n\ninterface IForwarder {\n error ForwarderNotContractAddressError();\n\n event WrapAndDeposit(address indexed account, IProduct indexed product, UFixed18 amount);\n\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\n function batcher() external view returns (IBatcher);\n function collateral() external view returns (ICollateral);\n function wrapAndDeposit(address account, IProduct product, UFixed18 amount) external;\n}\n" + }, + "contracts/interfaces/IIncentivizer.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./types/ProgramInfo.sol\";\nimport \"./IController.sol\";\nimport \"./IProduct.sol\";\n\ninterface IIncentivizer {\n event ProgramCreated(IProduct indexed product, uint256 indexed programId, ProgramInfo programInfo, UFixed18 programFeeAmount);\n event ProgramStarted(IProduct indexed product, uint256 indexed programId, uint256 version);\n event ProgramComplete(IProduct indexed product, uint256 indexed programId, uint256 version);\n event Claim(IProduct indexed product, address indexed account, uint256 indexed programId, UFixed18 amount);\n event FeeClaim(Token18 indexed token, UFixed18 amount);\n\n error IncentivizerNotAllowedError(IProduct product);\n error IncentivizerTooManyProgramsError();\n error IncentivizerNotProgramOwnerError(IProduct product, uint256 programId);\n error IncentivizerInvalidProgramError(IProduct product, uint256 programId);\n error IncentivizerBatchClaimArgumentMismatchError();\n\n function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory);\n function fees(Token18 token) external view returns (UFixed18);\n function initialize(IController controller_) external;\n function create(IProduct product, ProgramInfo calldata info) external returns (uint256);\n function complete(IProduct product, uint256 programId) external;\n function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external;\n function syncAccount(address account, IOracleProvider.OracleVersion memory currentOracleVersion) external;\n function claim(IProduct product, uint256[] calldata programIds) external;\n function claimFor(address account, IProduct product, uint256[] calldata programIds) external;\n function claim(IProduct[] calldata products, uint256[][] calldata programIds) external;\n function claimFee(Token18[] calldata tokens) external;\n function active(IProduct product) external view returns (uint256);\n function count(IProduct product) external view returns (uint256);\n function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18);\n function available(IProduct product, uint256 programId) external view returns (UFixed18);\n function versionStarted(IProduct product, uint256 programId) external view returns (uint256);\n function versionComplete(IProduct product, uint256 programId) external view returns (uint256);\n function owner(IProduct product, uint256 programId) external view returns (address);\n function treasury(IProduct product, uint256 programId) external view returns (address);\n}\n" + }, + "contracts/interfaces/IMultiInvoker.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\";\n\nimport \"./IController.sol\";\nimport \"./ICollateral.sol\";\nimport \"./IProduct.sol\";\n\ninterface IPerennialVault {\n event Deposit(address indexed sender, address indexed account, uint256 version, UFixed18 assets);\n event Redemption(address indexed sender, address indexed account, uint256 version, UFixed18 shares);\n event Claim(address indexed sender, address indexed account, UFixed18 assets);\n\n function deposit(UFixed18 assets, address account) external;\n function redeem(UFixed18 shares, address account) external;\n function claim(address account) external;\n}\n\ninterface IMultiInvoker {\n /// @dev Core protocol actions that can be composed\n enum PerennialAction {\n NO_OP,\n DEPOSIT,\n WITHDRAW,\n OPEN_TAKE,\n CLOSE_TAKE,\n OPEN_MAKE,\n CLOSE_MAKE,\n CLAIM,\n WRAP,\n UNWRAP,\n WRAP_AND_DEPOSIT,\n WITHDRAW_AND_UNWRAP,\n VAULT_DEPOSIT,\n VAULT_REDEEM,\n VAULT_CLAIM,\n VAULT_WRAP_AND_DEPOSIT\n }\n\n /// @dev Struct for action invocation\n struct Invocation {\n PerennialAction action;\n bytes args;\n }\n\n function initialize() external;\n function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\n function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\n function batcher() external view returns (IBatcher);\n function controller() external view returns (IController);\n function collateral() external view returns (ICollateral);\n function reserve() external view returns (IEmptySetReserve);\n function invoke(Invocation[] calldata invocations) external;\n}\n" + }, + "contracts/interfaces/IMultiInvokerRollup.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./IMultiInvoker.sol\";\n\ninterface IMultiInvokerRollup is IMultiInvoker {\n function addressNonce() external view returns(uint256);\n function addressCache(uint256 nonce) external view returns(address);\n function addressNonces(address addr) external view returns(uint256 nonce);\n}\n" + }, + "contracts/interfaces/IParamProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\";\nimport \"./types/PendingFeeUpdates.sol\";\n\ninterface IParamProvider {\n event MaintenanceUpdated(UFixed18 newMaintenance, uint256 version);\n event FundingFeeUpdated(UFixed18 newFundingFee, uint256 version);\n event MakerFeeUpdated(UFixed18 newMakerFee, uint256 version);\n event PendingMakerFeeUpdated(UFixed18 newMakerFee);\n event TakerFeeUpdated(UFixed18 newTakerFee, uint256 version);\n event PendingTakerFeeUpdated(UFixed18 newTakerFee);\n event PositionFeeUpdated(UFixed18 newPositionFee, uint256 version);\n event PendingPositionFeeUpdated(UFixed18 newPositionFee);\n event MakerLimitUpdated(UFixed18 newMakerLimit, uint256 version);\n event JumpRateUtilizationCurveUpdated(\n JumpRateUtilizationCurve,\n uint256 version\n );\n\n error ParamProviderInvalidParamValue();\n\n function maintenance() external view returns (UFixed18);\n function updateMaintenance(UFixed18 newMaintenance) external;\n function fundingFee() external view returns (UFixed18);\n function updateFundingFee(UFixed18 newFundingFee) external;\n function makerFee() external view returns (UFixed18);\n function updateMakerFee(UFixed18 newMakerFee) external;\n function takerFee() external view returns (UFixed18);\n function updateTakerFee(UFixed18 newTakerFee) external;\n function positionFee() external view returns (UFixed18);\n function updatePositionFee(UFixed18 newPositionFee) external;\n function makerLimit() external view returns (UFixed18);\n function updateMakerLimit(UFixed18 newMakerLimit) external;\n function utilizationCurve() external view returns (JumpRateUtilizationCurve memory);\n function updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) external;\n function pendingFeeUpdates() external view returns (PendingFeeUpdates memory);\n}\n" + }, + "contracts/interfaces/IPayoffProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./types/PayoffDefinition.sol\";\n\ninterface IPayoffProvider {\n event OracleUpdated(address newOracle, uint256 oracleVersion);\n\n error PayoffProviderInvalidOracle();\n error PayoffProviderInvalidPayoffDefinitionError();\n\n function oracle() external view returns (IOracleProvider);\n function payoffDefinition() external view returns (PayoffDefinition memory);\n function currentVersion() external view returns (IOracleProvider.OracleVersion memory);\n function atVersion(uint256 oracleVersion) external view returns (IOracleProvider.OracleVersion memory);\n}\n" + }, + "contracts/interfaces/IPerennialLens.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./IProduct.sol\";\nimport \"./ICollateral.sol\";\nimport \"./IController.sol\";\n\n/**\n * @title Lens contract to conveniently pull protocol, product, and userproduct data\n * @notice All functions should be called using `callStatic`\n */\ninterface IPerennialLens {\n /// @dev Snapshot of Protocol information\n struct ProtocolSnapshot {\n ICollateral collateral;\n IIncentivizer incentivizer;\n Token18 collateralToken;\n UFixed18 protocolFee;\n UFixed18 liquidationFee;\n UFixed18 minCollateral;\n bool paused;\n }\n\n /// @dev Snapshot of Product information\n struct ProductSnapshot {\n IProduct.ProductInfo productInfo;\n address productAddress;\n Fixed18 rate;\n Fixed18 dailyRate;\n IOracleProvider.OracleVersion latestVersion;\n UFixed18 maintenance;\n UFixed18 collateral;\n UFixed18 shortfall;\n PrePosition pre;\n Position position;\n UFixed18 productFee;\n UFixed18 protocolFee;\n Position openInterest;\n }\n\n /// @dev Snapshot of User state for a Product\n struct UserProductSnapshot {\n address productAddress;\n address userAddress;\n UFixed18 collateral;\n UFixed18 maintenance;\n PrePosition pre;\n Position position;\n bool liquidatable;\n bool liquidating;\n Position openInterest;\n UFixed18 fees;\n UFixed18 exposure;\n }\n\n // Protocol Values\n function controller() external view returns (IController);\n function collateral() external view returns (ICollateral);\n\n // Snapshot Functions for batch values\n function snapshot() external returns (ProtocolSnapshot memory);\n function snapshots(IProduct[] calldata productAddresses) external returns (ProductSnapshot[] memory);\n function snapshot(IProduct product) external returns (ProductSnapshot memory);\n function snapshots(address account, IProduct[] calldata productAddresses) external returns (UserProductSnapshot[] memory);\n function snapshot(address account, IProduct product) external returns (UserProductSnapshot memory);\n\n // Product Values\n function name(IProduct product) external view returns (string memory);\n function symbol(IProduct product) external view returns (string memory);\n function info(IProduct product) external view returns (IProduct.ProductInfo memory _info);\n function collateral(IProduct product) external returns (UFixed18);\n function shortfall(IProduct product) external returns (UFixed18);\n function pre(IProduct product) external returns (PrePosition memory);\n function fees(IProduct product) external returns (UFixed18 protocolFees, UFixed18 productFees);\n function position(IProduct product) external returns (Position memory);\n function globalPosition(IProduct product) external returns (PrePosition memory, Position memory);\n function latestVersion(IProduct product) external returns (IOracleProvider.OracleVersion memory);\n function atVersions(IProduct product, uint[] memory versions) external returns (IOracleProvider.OracleVersion[] memory prices);\n function rate(IProduct product) external returns (Fixed18);\n function openInterest(IProduct product) external returns (Position memory);\n function dailyRate(IProduct product) external returns (Fixed18);\n\n // UserProduct Values\n function collateral(address account, IProduct product) external returns (UFixed18);\n function maintenance(address account, IProduct product) external returns (UFixed18);\n function liquidatable(address account, IProduct product) external returns (bool);\n function liquidating(address account, IProduct product) external returns (bool);\n function pre(address account, IProduct product) external returns (PrePosition memory);\n function position(address account, IProduct product) external returns (Position memory);\n function userPosition(address account, IProduct product) external returns (PrePosition memory, Position memory);\n function fees(address account, IProduct product) external returns (UFixed18);\n function openInterest(address account, IProduct product) external returns (Position memory);\n function exposure(address account, IProduct product) external returns (UFixed18);\n function maintenanceRequired(\n address account,\n IProduct product,\n UFixed18 positionSize\n ) external returns (UFixed18);\n function unclaimedIncentiveRewards(address account, IProduct product)\n external\n returns (Token18[] memory tokens, UFixed18[] memory amounts);\n function unclaimedIncentiveRewards(\n address account,\n IProduct product,\n uint256[] calldata programIds\n ) external returns (Token18[] memory tokens, UFixed18[] memory amounts);\n}\n" + }, + "contracts/interfaces/IProduct.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\";\nimport \"./IPayoffProvider.sol\";\nimport \"./IParamProvider.sol\";\nimport \"./types/PayoffDefinition.sol\";\nimport \"./types/Position.sol\";\nimport \"./types/PrePosition.sol\";\nimport \"./types/Accumulator.sol\";\n\ninterface IProduct is IPayoffProvider, IParamProvider {\n /// @dev Product Creation parameters\n struct ProductInfo {\n /// @dev name of the product\n string name;\n\n /// @dev symbol of the product\n string symbol;\n\n /// @dev product payoff definition\n PayoffDefinition payoffDefinition;\n\n /// @dev oracle address\n IOracleProvider oracle;\n\n /// @dev product maintenance ratio\n UFixed18 maintenance;\n\n /// @dev product funding fee\n UFixed18 fundingFee;\n\n /// @dev product maker fee\n UFixed18 makerFee;\n\n /// @dev product taker fee\n UFixed18 takerFee;\n\n /// @dev product position fee share\n UFixed18 positionFee;\n\n /// @dev product maker limit\n UFixed18 makerLimit;\n\n /// @dev utulization curve definition\n JumpRateUtilizationCurve utilizationCurve;\n }\n\n event Settle(uint256 preVersion, uint256 toVersion);\n event AccountSettle(address indexed account, uint256 preVersion, uint256 toVersion);\n event MakeOpened(address indexed account, uint256 version, UFixed18 amount);\n event TakeOpened(address indexed account, uint256 version, UFixed18 amount);\n event MakeClosed(address indexed account, uint256 version, UFixed18 amount);\n event TakeClosed(address indexed account, uint256 version, UFixed18 amount);\n event ClosedUpdated(bool indexed newClosed, uint256 version);\n\n error ProductInsufficientLiquidityError(UFixed18 socializationFactor);\n error ProductDoubleSidedError();\n error ProductOverClosedError();\n error ProductInsufficientCollateralError();\n error ProductInLiquidationError();\n error ProductMakerOverLimitError();\n error ProductOracleBootstrappingError();\n error ProductClosedError();\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function initialize(ProductInfo calldata productInfo_) external;\n function settle() external;\n function settleAccount(address account) external;\n function openTake(UFixed18 amount) external;\n function openTakeFor(address account, UFixed18 amount) external;\n function closeTake(UFixed18 amount) external;\n function closeTakeFor(address account, UFixed18 amount) external;\n function openMake(UFixed18 amount) external;\n function openMakeFor(address account, UFixed18 amount) external;\n function closeMake(UFixed18 amount) external;\n function closeMakeFor(address account, UFixed18 amount) external;\n function closeAll(address account) external;\n function maintenance(address account) external view returns (UFixed18);\n function maintenanceNext(address account) external view returns (UFixed18);\n function isClosed(address account) external view returns (bool);\n function isLiquidating(address account) external view returns (bool);\n function position(address account) external view returns (Position memory);\n function pre(address account) external view returns (PrePosition memory);\n function latestVersion() external view returns (uint256);\n function positionAtVersion(uint256 oracleVersion) external view returns (Position memory);\n function pre() external view returns (PrePosition memory);\n function valueAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\n function shareAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\n function latestVersion(address account) external view returns (uint256);\n function rate(Position memory position) external view returns (Fixed18);\n function closed() external view returns (bool);\n function updateClosed(bool newClosed) external;\n function updateOracle(IOracleProvider newOracle) external;\n}\n" + }, + "contracts/interfaces/types/Accumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/Fixed18.sol\";\nimport \"./PackedAccumulator.sol\";\n\n/// @dev Accumulator type\nstruct Accumulator {\n /// @dev maker accumulator per share\n Fixed18 maker;\n /// @dev taker accumulator per share\n Fixed18 taker;\n}\nusing AccumulatorLib for Accumulator global;\n\n/**\n * @title AccountAccumulatorLib\n * @notice Library that surfaces math operations for the Accumulator type.\n * @dev Accumulators track the cumulative change in position value over time for the maker and taker positions\n * respectively. Account-level accumulators can then use two of these values `a` and `a'` to compute the\n * change in position value since last sync. This change in value is then used to compute P&L and fees.\n */\nlibrary AccumulatorLib {\n /**\n * @notice Creates a packed accumulator from an accumulator\n * @param self an accumulator\n * @return New packed accumulator\n */\n function pack(Accumulator memory self) internal pure returns (PackedAccumulator memory) {\n return PackedAccumulator({maker: self.maker.pack(), taker: self.taker.pack()});\n }\n\n /**\n * @notice Adds two accumulators together\n * @param a The first accumulator to sum\n * @param b The second accumulator to sum\n * @return The resulting summed accumulator\n */\n function add(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\n return Accumulator({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\n }\n\n /**\n * @notice Subtracts accumulator `b` from `a`\n * @param a The accumulator to subtract from\n * @param b The accumulator to subtract\n * @return The resulting subtracted accumulator\n */\n function sub(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\n return Accumulator({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\n }\n\n /**\n * @notice Multiplies two accumulators together\n * @param a The first accumulator to multiply\n * @param b The second accumulator to multiply\n * @return The resulting multiplied accumulator\n */\n function mul(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\n return Accumulator({maker: a.maker.mul(b.maker), taker: a.taker.mul(b.taker)});\n }\n\n /**\n * @notice Sums the maker and taker together from a single accumulator\n * @param self The struct to operate on\n * @return The sum of its maker and taker\n */\n function sum(Accumulator memory self) internal pure returns (Fixed18) {\n return self.maker.add(self.taker);\n }\n}\n" + }, + "contracts/interfaces/types/PackedAccumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/PackedFixed18.sol\";\nimport \"./Accumulator.sol\";\n\n/// @dev PackedAccumulator type\nstruct PackedAccumulator {\n /// @dev maker accumulator per share\n PackedFixed18 maker;\n /// @dev taker accumulator per share\n PackedFixed18 taker;\n}\nusing PackedAccumulatorLib for PackedAccumulator global;\n\n/**\n * @title PackedAccumulatorLib\n * @dev A packed version of the Accumulator which takes up a single storage slot using `PackedFixed18` values.\n * @notice Library for the packed Accumulator type.\n */\nlibrary PackedAccumulatorLib {\n /**\n * @notice Creates an accumulator from a packed accumulator\n * @param self packed accumulator\n * @return New accumulator\n */\n function unpack(PackedAccumulator memory self) internal pure returns (Accumulator memory) {\n return Accumulator({maker: self.maker.unpack(), taker: self.taker.unpack()});\n }\n}\n" + }, + "contracts/interfaces/types/PackedPosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/PackedUFixed18.sol\";\nimport \"./Position.sol\";\n\n/// @dev PackedPosition type\nstruct PackedPosition {\n /// @dev Quantity of the maker position\n PackedUFixed18 maker;\n /// @dev Quantity of the taker position\n PackedUFixed18 taker;\n}\nusing PackedPositionLib for PackedPosition global;\n\n/**\n * @title PackedPositionLib\n * @dev A packed version of the Position which takes up a single storage slot using `PackedFixed18` values.\n * @notice Library for the packed Position type.\n */\nlibrary PackedPositionLib {\n /**\n * @notice Creates an position from a packed position\n * @param self packed position\n * @return New position\n */\n function unpack(PackedPosition memory self) internal pure returns (Position memory) {\n return Position({maker: self.maker.unpack(), taker: self.taker.unpack()});\n }\n}\n" + }, + "contracts/interfaces/types/PayoffDefinition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"../../interfaces/IContractPayoffProvider.sol\";\n\n/// @dev PayoffDefinition tyoe\nstruct PayoffDefinition {\n PayoffDefinitionLib.PayoffType payoffType;\n PayoffDefinitionLib.PayoffDirection payoffDirection;\n bytes30 data;\n}\nusing PayoffDefinitionLib for PayoffDefinition global;\ntype PayoffDefinitionStorage is bytes32;\nusing PayoffDefinitionStorageLib for PayoffDefinitionStorage global;\n\n/**\n * @title PayoffDefinitionLib\n * @dev Library that surfaces logic for PayoffDefinition type functionality\n * @notice Library for the PayoffDefinition type. Performs validity and price transformation\n based on the payoff definition type.\n */\nlibrary PayoffDefinitionLib {\n using Address for address;\n\n error PayoffDefinitionUnsupportedTransform(PayoffType payoffType, PayoffDirection payoffDirection);\n error PayoffDefinitionNotContract(PayoffType payoffType, bytes30 data);\n\n /// @dev Payoff function type enum\n enum PayoffType { PASSTHROUGH, CONTRACT }\n enum PayoffDirection { LONG, SHORT }\n\n /**\n * @notice Checks validity of the payoff definition\n * @param self a payoff definition\n * @return Whether the payoff definition is valid for it's given type\n */\n function valid(PayoffDefinition memory self) internal view returns (bool) {\n if (self.payoffType == PayoffType.CONTRACT) return address(_providerContract(self)).isContract();\n\n // All other payoff types should have no data\n return uint(bytes32(self.data)) == 0;\n }\n\n /**\n * @notice Transforms a price based on the payoff definition\n * @param self a payoff definition\n * @param price raw oracle price\n * @return Price transformed by the payoff definition function\n */\n function transform(\n PayoffDefinition memory self,\n Fixed18 price\n ) internal view returns (Fixed18) {\n PayoffType payoffType = self.payoffType;\n PayoffDirection payoffDirection = self.payoffDirection;\n Fixed18 transformedPrice;\n\n // First get the price depending on the type\n if (payoffType == PayoffType.PASSTHROUGH) transformedPrice = price;\n else if (payoffType == PayoffType.CONTRACT) transformedPrice = _payoffFromContract(self, price);\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\n\n // Then transform it depending on the direction flag\n if (self.payoffDirection == PayoffDirection.LONG) return transformedPrice;\n else if (self.payoffDirection == PayoffDirection.SHORT) return transformedPrice.mul(Fixed18Lib.NEG_ONE);\n else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\n }\n\n /**\n * @notice Parses the data field into an address\n * @dev Reverts if payoffType is not CONTRACT\n * @param self a payoff definition\n * @return IContractPayoffProvider address\n */\n function _providerContract(\n PayoffDefinition memory self\n ) private pure returns (IContractPayoffProvider) {\n if (self.payoffType != PayoffType.CONTRACT) revert PayoffDefinitionNotContract(self.payoffType, self.data);\n // Shift to pull the last 20 bytes, then cast to an address\n return IContractPayoffProvider(address(bytes20(self.data << 80)));\n }\n\n /**\n * @notice Performs a price transformation by calling the underlying payoff contract\n * @param self a payoff definition\n * @param price raw oracle price\n * @return Price transformed by the payoff definition function on the contract\n */\n function _payoffFromContract(\n PayoffDefinition memory self,\n Fixed18 price\n ) private view returns (Fixed18) {\n bytes memory ret = address(_providerContract(self)).functionStaticCall(\n abi.encodeCall(IContractPayoffProvider.payoff, price)\n );\n return Fixed18.wrap(abi.decode(ret, (int256)));\n }\n}\n\n/**\n * @title PayoffDefinitionStorageLib\n * @notice Library that surfaces storage read and writes for the PayoffDefinition type\n */\nlibrary PayoffDefinitionStorageLib {\n function read(PayoffDefinitionStorage self) internal view returns (PayoffDefinition memory) {\n return _storagePointer(self);\n }\n\n function store(PayoffDefinitionStorage self, PayoffDefinition memory value) internal {\n PayoffDefinition storage storagePointer = _storagePointer(self);\n\n storagePointer.payoffType = value.payoffType;\n storagePointer.payoffDirection = value.payoffDirection;\n storagePointer.data = value.data;\n }\n\n function _storagePointer(\n PayoffDefinitionStorage self\n ) private pure returns (PayoffDefinition storage pointer) {\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\n }\n}\n" + }, + "contracts/interfaces/types/PendingFeeUpdates.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\n\n/// @dev PendingFeeUpdates type. Fees can be between 0 and 1 ** 10^18, so uint64 is sufficient\nstruct PendingFeeUpdates {\n bool makerFeeUpdated;\n uint64 pendingMakerFee;\n bool takerFeeUpdated;\n uint64 pendingTakerFee;\n bool positionFeeUpdated;\n uint64 pendingPositionFee;\n}\nusing PendingFeeUpdatesLib for PendingFeeUpdates global;\ntype PendingFeeUpdatesStorage is bytes32;\nusing PendingFeeUpdatesStorageLib for PendingFeeUpdatesStorage global;\n\n/**\n * @title PendingFeeUpdatesLib\n * @dev Library that surfaces convenience functions for the PendingFeeUpdates type\n * @notice Library for the PendingFeeUpdates type. Allows for setting and reading fee updates and clearing state\n */\nlibrary PendingFeeUpdatesLib {\n error PendingFeeUpdatesUnsupportedValue(UFixed18 value);\n\n /**\n * @notice Updates the pending maker fee to `newMakerFee` and sets the `makerFeeUpdated` flag\n * @dev Reverts if `newMakerFee` is invalid\n * @param self PendingFeeUpdates struct\n * @param newMakerFee new maker fee value\n */\n function updateMakerFee(PendingFeeUpdates memory self, UFixed18 newMakerFee) internal pure {\n if (UFixed18.unwrap(newMakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newMakerFee);\n self.pendingMakerFee = uint64(UFixed18.unwrap(newMakerFee));\n self.makerFeeUpdated = true;\n }\n\n /// @dev Returns the UFixed18-wrapped pending maker fee\n function makerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(self.pendingMakerFee));\n }\n\n /**\n * @notice Updates the pending taker fee to `newTakerFee` and sets the `takerFeeUpdated` flag\n * @dev Reverts if `newTakerFee` is invalid\n * @param self PendingFeeUpdates struct\n * @param newTakerFee new taker fee value\n */\n function updateTakerFee(PendingFeeUpdates memory self, UFixed18 newTakerFee) internal pure {\n if (UFixed18.unwrap(newTakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newTakerFee);\n self.pendingTakerFee = uint64(UFixed18.unwrap(newTakerFee));\n self.takerFeeUpdated = true;\n }\n\n /// @dev Returns the UFixed18-wrapped pending taker fee\n function takerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(self.pendingTakerFee));\n }\n\n /**\n * @notice Updates the pending position fee to `newPositionFee` and sets the `positionFeeUpdated` flag\n * @dev Reverts if `newPositionFee` is invalid\n * @param self PendingFeeUpdates struct\n * @param newPositionFee new position fee value\n */\n function updatePositionFee(PendingFeeUpdates memory self, UFixed18 newPositionFee) internal pure {\n if (UFixed18.unwrap(newPositionFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newPositionFee);\n self.pendingPositionFee = uint64(UFixed18.unwrap(newPositionFee));\n self.positionFeeUpdated = true;\n }\n\n /// @dev Returns the UFixed18-wrapped pending position fee\n function positionFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\n return UFixed18.wrap(uint256(self.pendingPositionFee));\n }\n\n /// @dev Returns true if any of the updated flags are true\n function hasUpdates(PendingFeeUpdates memory self) internal pure returns (bool) {\n return self.makerFeeUpdated || self.takerFeeUpdated || self.positionFeeUpdated;\n }\n\n /// @dev Resets all struct values to defaults\n function clear(PendingFeeUpdates memory self) internal pure {\n self.makerFeeUpdated = false;\n self.pendingMakerFee = 0;\n self.takerFeeUpdated = false;\n self.pendingTakerFee = 0;\n self.positionFeeUpdated = false;\n self.pendingPositionFee = 0;\n }\n}\n\n/**\n * @title PendingFeeUpdatesStorageLib\n * @notice Library that surfaces storage read and writes for the PendingFeeUpdates type\n */\nlibrary PendingFeeUpdatesStorageLib {\n struct PendingFeeUpdatesStoragePointer {\n PendingFeeUpdates value;\n }\n\n function read(PendingFeeUpdatesStorage self) internal view returns (PendingFeeUpdates memory) {\n return _storagePointer(self).value;\n }\n\n function store(PendingFeeUpdatesStorage self, PendingFeeUpdates memory value) internal {\n _storagePointer(self).value = value;\n }\n\n function _storagePointer(\n PendingFeeUpdatesStorage self\n ) private pure returns (PendingFeeUpdatesStoragePointer storage pointer) {\n /// @solidity memory-safe-assembly\n assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\n }\n}\n" + }, + "contracts/interfaces/types/Position.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"../IProduct.sol\";\nimport \"./Accumulator.sol\";\nimport \"./PrePosition.sol\";\nimport \"./PackedPosition.sol\";\n\n/// @dev Position type\nstruct Position {\n /// @dev Quantity of the maker position\n UFixed18 maker;\n /// @dev Quantity of the taker position\n UFixed18 taker;\n}\nusing PositionLib for Position global;\n\n/**\n * @title PositionLib\n * @notice Library that surfaces math and settlement computations for the Position type.\n * @dev Positions track the current quantity of the account's maker and taker positions respectively\n * denominated as a unit of the product's payoff function.\n */\nlibrary PositionLib {\n /**\n * @notice Creates a packed position from an position\n * @param self A position\n * @return New packed position\n */\n function pack(Position memory self) internal pure returns (PackedPosition memory) {\n return PackedPosition({maker: self.maker.pack(), taker: self.taker.pack()});\n }\n\n /**\n * @notice Returns whether the position is fully empty\n * @param self A position\n * @return Whether the position is empty\n */\n function isEmpty(Position memory self) internal pure returns (bool) {\n return self.maker.isZero() && self.taker.isZero();\n }\n\n /**\n * @notice Adds position `a` and `b` together, returning the result\n * @param a The first position to sum\n * @param b The second position to sum\n * @return Resulting summed position\n */\n function add(Position memory a, Position memory b) internal pure returns (Position memory) {\n return Position({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\n }\n\n /**\n * @notice Subtracts position `b` from `a`, returning the result\n * @param a The position to subtract from\n * @param b The position to subtract\n * @return Resulting subtracted position\n */\n function sub(Position memory a, Position memory b) internal pure returns (Position memory) {\n return Position({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\n }\n\n /**\n * @notice Multiplies position `self` by accumulator `accumulator` and returns the resulting accumulator\n * @param self The Position to operate on\n * @param accumulator The accumulator to multiply by\n * @return Resulting multiplied accumulator\n */\n function mul(Position memory self, Accumulator memory accumulator) internal pure returns (Accumulator memory) {\n return Accumulator({\n maker: Fixed18Lib.from(self.maker).mul(accumulator.maker),\n taker: Fixed18Lib.from(self.taker).mul(accumulator.taker)\n });\n }\n\n /**\n * @notice Scales position `self` by fixed-decimal `scale` and returns the resulting position\n * @param self The Position to operate on\n * @param scale The Fixed-decimal to scale by\n * @return Resulting scaled position\n */\n function mul(Position memory self, UFixed18 scale) internal pure returns (Position memory) {\n return Position({maker: self.maker.mul(scale), taker: self.taker.mul(scale)});\n }\n\n /**\n * @notice Divides position `self` by `b` and returns the resulting accumulator\n * @param self The Position to operate on\n * @param b The number to divide by\n * @return Resulting divided accumulator\n */\n function div(Position memory self, uint256 b) internal pure returns (Accumulator memory) {\n return Accumulator({\n maker: Fixed18Lib.from(self.maker).div(Fixed18Lib.from(UFixed18Lib.from(b))),\n taker: Fixed18Lib.from(self.taker).div(Fixed18Lib.from(UFixed18Lib.from(b)))\n });\n }\n\n /**\n * @notice Returns the maximum of `self`'s maker and taker values\n * @param self The struct to operate on\n * @return Resulting maximum value\n */\n function max(Position memory self) internal pure returns (UFixed18) {\n return UFixed18Lib.max(self.maker, self.taker);\n }\n\n /**\n * @notice Sums the maker and taker together from a single position\n * @param self The struct to operate on\n * @return The sum of its maker and taker\n */\n function sum(Position memory self) internal pure returns (UFixed18) {\n return self.maker.add(self.taker);\n }\n\n /**\n * @notice Computes the next position after the pending-settlement position delta is included\n * @param self The current Position\n * @param pre The pending-settlement position delta\n * @return Next Position\n */\n function next(Position memory self, PrePosition memory pre) internal pure returns (Position memory) {\n return sub(add(self, pre.openPosition), pre.closePosition);\n }\n\n /**\n * @notice Returns the settled position at oracle version `toOracleVersion`\n * @dev Checks if a new position is ready to be settled based on the provided `toOracleVersion`\n * and `pre` and returns accordingly\n * @param self The current Position\n * @param pre The pending-settlement position delta\n * @param toOracleVersion The oracle version to settle to\n * @return Settled position at oracle version\n * @return Whether a new position was settled\n */\n function settled(\n Position memory self,\n PrePosition memory pre,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal pure returns (Position memory, bool) {\n return pre.canSettle(toOracleVersion) ? (next(self, pre), true) : (self, false);\n }\n\n /**\n * @notice Returns the socialization factor for the current position\n * @dev Socialization account for the case where `taker` > `maker` temporarily due to a liquidation\n * on the maker side. This dampens the taker's exposure pro-rata to ensure that the maker side\n * is never exposed over 1 x short.\n * @param self The Position to operate on\n * @return Socialization factor\n */\n function socializationFactor(Position memory self) internal pure returns (UFixed18) {\n return self.taker.isZero() ? UFixed18Lib.ONE : UFixed18Lib.min(UFixed18Lib.ONE, self.maker.div(self.taker));\n }\n}\n" + }, + "contracts/interfaces/types/PrePosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"./Position.sol\";\nimport \"../IProduct.sol\";\n\n/// @dev PrePosition type\nstruct PrePosition {\n /// @dev Oracle version at which the new position delta was recorded\n uint256 oracleVersion;\n\n /// @dev Size of position to open at oracle version\n Position openPosition;\n\n /// @dev Size of position to close at oracle version\n Position closePosition;\n}\nusing PrePositionLib for PrePosition global;\n\n/**\n * @title PrePositionLib\n * @notice Library that manages a pre-settlement position delta.\n * @dev PrePositions track the currently awaiting-settlement deltas to a settled Position. These are\n * Primarily necessary to introduce lag into the settlement system such that oracle lag cannot be\n * gamed to a user's advantage. When a user opens or closes a new position, it sits as a PrePosition\n * for one oracle version until it's settle into the Position, making it then effective. PrePositions\n * are automatically settled at the correct oracle version even if a flywheel call doesn't happen until\n * several version into the future by using the historical version lookups in the corresponding \"Versioned\"\n * global state types.\n */\nlibrary PrePositionLib {\n /**\n * @notice Returns whether there is no pending-settlement position delta\n * @param self The struct to operate on\n * @return Whether the pending-settlement position delta is empty\n */\n function isEmpty(PrePosition memory self) internal pure returns (bool) {\n return self.openPosition.isEmpty() && self.closePosition.isEmpty();\n }\n\n /**\n * @notice Increments the maker side of the open position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The position amount to open\n */\n function openMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.openPosition.maker = self.openPosition.maker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Increments the maker side of the close position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The maker position amount to close\n */\n function closeMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.closePosition.maker = self.closePosition.maker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Increments the taker side of the open position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The taker position amount to open\n */\n function openTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.openPosition.taker = self.openPosition.taker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Increments the taker side of the close position delta\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @param amount The taker position amount to close\n */\n function closeTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\n self.closePosition.taker = self.closePosition.taker.add(amount);\n self.oracleVersion = currentVersion;\n }\n\n /**\n * @notice Returns whether the the pending position delta can be settled at version `toOracleVersion`\n * @dev Pending-settlement positions deltas can be settled (1) oracle version after they are recorded\n * @param self The struct to operate on\n * @param toOracleVersion The potential oracle version to settle\n * @return Whether the position delta can be settled\n */\n function canSettle(\n PrePosition memory self,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal pure returns (bool) {\n return !isEmpty(self) && toOracleVersion.version > self.oracleVersion;\n }\n\n /**\n * @notice Computes the fee incurred for opening or closing the pending-settlement position\n * @dev Must be called from a valid product to get the proper fee amounts\n * @param self The struct to operate on\n * @param latestOracleVersion The oracle version at which position was modified\n * @return The maker / taker fee incurred\n */\n function computeFee(\n PrePosition memory self,\n IOracleProvider.OracleVersion memory latestOracleVersion\n ) internal view returns (Position memory) {\n Position memory positionDelta = self.openPosition.add(self.closePosition);\n\n (UFixed18 makerNotional, UFixed18 takerNotional) = (\n Fixed18Lib.from(positionDelta.maker).mul(latestOracleVersion.price).abs(),\n Fixed18Lib.from(positionDelta.taker).mul(latestOracleVersion.price).abs()\n );\n\n IProduct product = IProduct(address(this));\n return Position(makerNotional.mul(product.makerFee()), takerNotional.mul(product.takerFee()));\n }\n\n /**\n * @notice Computes the next oracle version to settle\n * @dev - If there is no pending-settlement position delta, returns the current oracle version\n * - Otherwise returns the oracle version at which the pending-settlement position delta can be first settled\n *\n * Corresponds to point (b) in the Position settlement flow\n * @param self The struct to operate on\n * @param currentVersion The current oracle version index\n * @return Next oracle version to settle\n */\n function settleVersion(PrePosition storage self, uint256 currentVersion) internal view returns (uint256) {\n uint256 _oracleVersion = self.oracleVersion;\n return _oracleVersion == 0 ? currentVersion : _oracleVersion + 1;\n }\n}\n" + }, + "contracts/interfaces/types/ProgramInfo.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"../IProduct.sol\";\nimport \"./Position.sol\";\nimport \"./Accumulator.sol\";\n\n/// @dev ProgramInfo type\nstruct ProgramInfo {\n /// @dev Coordinator for this program\n uint256 coordinatorId;\n\n /// @dev Amount of total maker and taker rewards\n Position amount;\n\n /// @dev start timestamp of the program\n uint256 start;\n\n /// @dev duration of the program (in seconds)\n uint256 duration;\n\n /**\n * @dev Reward ERC20 token contract\n * @notice Perennial does not support non-standard ERC20s as reward tokens for incentive programs, including,\n but not limited to: fee on transfer and rebase tokens. Using such a non-standard token will likely\n result in loss of funds.\n */\n Token18 token;\n}\nusing ProgramInfoLib for ProgramInfo global;\n\n/**\n * @title ProgramInfoLib\n * @notice Library that snapshots the static information for a single program.\n * @dev This information does not change during the operation of a program.\n */\nlibrary ProgramInfoLib {\n uint256 private constant MIN_DURATION = 1 days;\n uint256 private constant MAX_DURATION = 2 * 365 days;\n\n error ProgramInvalidStartError();\n error ProgramInvalidDurationError();\n\n /**\n * @notice Validates and creates a new Program\n * @dev Reverts for invalid programInfos\n * @param programInfo Un-sanitized static program information\n */\n function validate(ProgramInfo memory programInfo) internal view {\n if (isStarted(programInfo, block.timestamp)) revert ProgramInvalidStartError();\n if (programInfo.duration < MIN_DURATION || programInfo.duration > MAX_DURATION) revert ProgramInvalidDurationError();\n }\n\n /**\n * @notice Computes a new program info with the fee taken out of the amount\n * @param programInfo Original program info\n * @param incentivizationFee The incentivization fee\n * @return New program info\n * @return Fee amount\n */\n function deductFee(ProgramInfo memory programInfo, UFixed18 incentivizationFee)\n internal pure returns (ProgramInfo memory, UFixed18) {\n Position memory newProgramAmount = programInfo.amount.mul(UFixed18Lib.ONE.sub(incentivizationFee));\n UFixed18 programFeeAmount = programInfo.amount.sub(newProgramAmount).sum();\n programInfo.amount = newProgramAmount;\n return (programInfo, programFeeAmount);\n }\n\n /**\n * @notice Returns the maker and taker amounts per position share\n * @param self The ProgramInfo to operate on\n * @return programFee Amounts per share\n */\n function amountPerShare(ProgramInfo memory self) internal pure returns (Accumulator memory) {\n return self.amount.div(self.duration);\n }\n\n /**\n * @notice Returns whether the program has started by timestamp `timestamp`\n * @param self The ProgramInfo to operate on\n * @param timestamp Timestamp to check for\n * @return Whether the program has started\n */\n function isStarted(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\n return timestamp >= self.start;\n }\n\n /**\n * @notice Returns whether the program is completed by timestamp `timestamp`\n * @param self The ProgramInfo to operate on\n * @param timestamp Timestamp to check for\n * @return Whether the program is completed\n */\n function isComplete(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\n return timestamp >= (self.start + self.duration);\n }\n}\n" + }, + "contracts/multiinvoker/MultiInvoker.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\n\nimport \"../interfaces/IMultiInvoker.sol\";\n\ncontract MultiInvoker is IMultiInvoker, UInitializable {\n /// @dev USDC stablecoin address\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n /// @dev DSU address\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n\n /// @dev Batcher address\n IBatcher public immutable batcher;\n\n /// @dev Controller address\n IController public immutable controller;\n\n /// @dev Collateral address\n ICollateral public immutable collateral;\n\n /// @dev Reserve address\n IEmptySetReserve public immutable reserve;\n\n /**\n * @notice Initializes the immutable contract state\n * @dev Called at implementation instantiate and constant for that implementation.\n * @param usdc_ USDC stablecoin address\n * @param batcher_ Protocol Batcher address\n * @param reserve_ EmptySet Reserve address\n * @param controller_ Protocol Controller address\n */\n constructor(Token6 usdc_, IBatcher batcher_, IEmptySetReserve reserve_, IController controller_) {\n USDC = usdc_;\n batcher = batcher_;\n controller = controller_;\n collateral = controller.collateral();\n DSU = collateral.token();\n reserve = reserve_;\n }\n\n /**\n * @notice Initializes the contract state\n * @dev Must be called atomically as part of the upgradeable proxy deployment to\n * avoid front-running\n */\n function initialize() external initializer(2) {\n if (address(batcher) != address(0)) {\n DSU.approve(address(batcher), UFixed18Lib.ZERO);\n DSU.approve(address(batcher));\n USDC.approve(address(batcher), UFixed18Lib.ZERO);\n USDC.approve(address(batcher));\n }\n\n DSU.approve(address(collateral), UFixed18Lib.ZERO);\n DSU.approve(address(collateral));\n\n DSU.approve(address(reserve), UFixed18Lib.ZERO);\n DSU.approve(address(reserve));\n USDC.approve(address(reserve), UFixed18Lib.ZERO);\n USDC.approve(address(reserve));\n }\n\n /**\n * @notice Executes a list of invocations in order\n * @param invocations The list of invocations to execute in order\n */\n function invoke(Invocation[] calldata invocations) external {\n // ACTION TYPES\n // \n // 0000 0000\n // \n\n for (uint256 i = 0; i < invocations.length; i++) {\n Invocation memory invocation = invocations[i];\n\n // Deposit from `msg.sender` into `account`s `product` collateral account\n if (invocation.action == PerennialAction.DEPOSIT) {\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n depositTo(account, product, amount);\n\n // Withdraw from `msg.sender`s `product` collateral account to `receiver`\n } else if (invocation.action == PerennialAction.WITHDRAW) {\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n collateral.withdrawFrom(msg.sender, receiver, product, amount);\n\n // Open a take position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.OPEN_TAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n product.openTakeFor(msg.sender, amount);\n\n // Close a take position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.CLOSE_TAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n product.closeTakeFor(msg.sender, amount);\n\n // Open a make position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.OPEN_MAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n product.openMakeFor(msg.sender, amount);\n\n // Close a make position on behalf of `msg.sender`\n } else if (invocation.action == PerennialAction.CLOSE_MAKE) {\n (IProduct product, UFixed18 amount) = abi.decode(invocation.args, (IProduct, UFixed18));\n product.closeMakeFor(msg.sender, amount);\n\n // Claim `msg.sender`s incentive reward for `product` programs\n } else if (invocation.action == PerennialAction.CLAIM) {\n (IProduct product, uint256[] memory programIds) = abi.decode(invocation.args, (IProduct, uint256[]));\n controller.incentivizer().claimFor(msg.sender, product, programIds);\n\n // Wrap `msg.sender`s USDC into DSU and return the DSU to `account`\n } else if (invocation.action == PerennialAction.WRAP) {\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\n wrap(receiver, amount);\n\n // Unwrap `msg.sender`s DSU into USDC and return the USDC to `account`\n } else if (invocation.action == PerennialAction.UNWRAP) {\n (address receiver, UFixed18 amount) = abi.decode(invocation.args, (address, UFixed18));\n unwrap(receiver, amount);\n\n // Wrap `msg.sender`s USDC into DSU and deposit into `account`s `product` collateral account\n } else if (invocation.action == PerennialAction.WRAP_AND_DEPOSIT) {\n (address account, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n wrapAndDeposit(account, product, amount);\n }\n\n // Withdraw DSU from `msg.sender`s `product` collateral account, unwrap into USDC, and return the USDC to `receiver`\n else if (invocation.action == PerennialAction.WITHDRAW_AND_UNWRAP) {\n (address receiver, IProduct product, UFixed18 amount) = abi.decode(invocation.args, (address, IProduct, UFixed18));\n withdrawAndUnwrap(receiver, product, amount);\n }\n\n // Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account`\n else if (invocation.action == PerennialAction.VAULT_DEPOSIT) {\n (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18));\n vaultDeposit(account, vault, amount);\n }\n\n // Redeem `shares` from from `vault` on behalf of `msg.sender`\n else if (invocation.action == PerennialAction.VAULT_REDEEM) {\n (IPerennialVault vault, UFixed18 shares) = abi.decode(invocation.args, (IPerennialVault, UFixed18));\n vault.redeem(shares, msg.sender);\n }\n\n // Claim assets from `vault` on behalf of `owner`\n else if (invocation.action == PerennialAction.VAULT_CLAIM) {\n (address owner, IPerennialVault vault) = abi.decode(invocation.args, (address, IPerennialVault));\n vault.claim(owner);\n }\n\n // Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault`\n else if (invocation.action == PerennialAction.VAULT_WRAP_AND_DEPOSIT) {\n (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18));\n vaultWrapAndDeposit(account, vault, amount);\n }\n }\n }\n\n /**\n * @notice Deposits `amount` DSU from `msg.sender` into `account`s `product` collateral account\n * @param account Account to deposit funds on behalf of\n * @param product Product to deposit funds for\n * @param amount Amount of DSU to deposit into the collateral account\n */\n function depositTo(address account, IProduct product, UFixed18 amount) internal {\n // Pull the token from the `msg.sender`\n DSU.pull(msg.sender, amount);\n\n // Deposit the amount to the collateral account\n collateral.depositTo(account, product, amount);\n }\n\n /**\n * @notice Wraps `amount` USDC into DSU, pulling from `msg.sender` and sending to `receiver`\n * @param receiver Address to receive the DSU\n * @param amount Amount of USDC to wrap\n */\n function wrap(address receiver, UFixed18 amount) internal {\n // Pull USDC from the `msg.sender`\n USDC.pull(msg.sender, amount, true);\n\n _wrap(receiver, amount);\n }\n\n /**\n * @notice Unwraps `amount` DSU into USDC, pulling from `msg.sender` and sending to `receiver`\n * @param receiver Address to receive the USDC\n * @param amount Amount of DSU to unwrap\n */\n function unwrap(address receiver, UFixed18 amount) internal {\n // Pull the token from the `msg.sender`\n DSU.pull(msg.sender, amount);\n\n _unwrap(receiver, amount);\n }\n\n /**\n * @notice Wraps `amount` USDC from `msg.sender` into DSU, then deposits the USDC into `account`s `product` collateral account\n * @param account Account to deposit funds on behalf of\n * @param product Product to deposit funds for\n * @param amount Amount of USDC to deposit into the collateral account\n */\n function wrapAndDeposit(address account, IProduct product, UFixed18 amount) internal {\n // Pull USDC from the `msg.sender`\n USDC.pull(msg.sender, amount, true);\n\n _wrap(address(this), amount);\n\n // Deposit the amount to the collateral account\n collateral.depositTo(account, product, amount);\n }\n\n /**\n * @notice Withdraws `amount` DSU from `msg.sender`s `product` collateral account, then unwraps the DSU into USDC and sends it to `receiver`\n * @param receiver Address to receive the USDC\n * @param product Product to withdraw funds for\n * @param amount Amount of DSU to withdraw from the collateral account\n */\n function withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) internal {\n // Withdraw the amount from the collateral account\n collateral.withdrawFrom(msg.sender, address(this), product, amount);\n\n _unwrap(receiver, amount);\n }\n\n /**\n * @notice Deposit `amount` DSU from `msg.sender` into `vault` on behalf of `account`\n * @param account Address to receive the vault shares\n * @param vault Vault to deposit funds into\n * @param amount Amount of DSU to deposit into the vault\n */\n function vaultDeposit(address account, IPerennialVault vault, UFixed18 amount) internal {\n // Pull the DSU from the user\n DSU.pull(msg.sender, amount);\n\n // Just-in-time approval to the vault for the amount being deposited\n DSU.approve(address(vault), amount);\n\n // Deposit the DSU to the vault, crediting shares to `account`\n vault.deposit(amount, account);\n }\n\n /**\n * @notice Wrap `amount` USDC from `msg.sender` and deposit the DSU into the `vault`\n * @param account Address to receive the vault shares\n * @param vault Vault to deposit funds into\n * @param amount Amount of USDC to wrap and deposit into the vault\n */\n function vaultWrapAndDeposit(address account, IPerennialVault vault, UFixed18 amount) internal {\n // Pull USDC from the `msg.sender`\n USDC.pull(msg.sender, amount, true);\n\n _wrap(address(this), amount);\n\n // Just-in-time approval to the vault for the amount being deposited\n DSU.approve(address(vault), amount);\n\n // Deposit the DSU to the vault, crediting shares to `account`\n vault.deposit(amount, account);\n }\n\n /**\n * @notice Helper function to wrap `amount` USDC from `msg.sender` into DSU using the batcher or reserve\n * @param receiver Address to receive the DSU\n * @param amount Amount of USDC to wrap\n */\n function _wrap(address receiver, UFixed18 amount) internal {\n // If the batcher is 0 or doesn't have enough for this wrap, go directly to the reserve\n if (address(batcher) == address(0) || amount.gt(DSU.balanceOf(address(batcher)))) {\n reserve.mint(amount);\n if (receiver != address(this)) DSU.push(receiver, amount);\n } else {\n // Wrap the USDC into DSU and return to the receiver\n batcher.wrap(amount, receiver);\n }\n }\n\n /**\n * @notice Helper function to unwrap `amount` DSU into USDC and send to `receiver`\n * @param receiver Address to receive the USDC\n * @param amount Amount of DSU to unwrap\n */\n function _unwrap(address receiver, UFixed18 amount) internal {\n // If the batcher is 0 or doesn't have enough for this unwrap, go directly to the reserve\n if (address(batcher) == address(0) || amount.gt(USDC.balanceOf(address(batcher)))) {\n reserve.redeem(amount);\n if (receiver != address(this)) USDC.push(receiver, amount);\n } else {\n // Unwrap the DSU into USDC and return to the receiver\n batcher.unwrap(amount, receiver);\n }\n }\n}\n" + }, + "contracts/multiinvoker/MultiInvokerRollup.sol": { + "content": "pragma solidity ^0.8.0;\n\nimport \"./MultiInvoker.sol\";\n\n// import \"forge-std/Test.sol\";\n\ncontract MultiInvokerRollup is MultiInvoker {\n\n event AddressAddedToCache(address indexed addr, uint256 nonce);\n\n uint256 public addressNonce;\n mapping(uint => address) public addressCache;\n mapping(address => uint) public addressNonces;\n\n \n constructor(\n Token6 usdc_,\n IBatcher batcher_,\n IEmptySetReserve reserve_,\n IController controller_\n ) MultiInvoker(\n usdc_,\n batcher_,\n reserve_,\n controller_\n ) { }\n\n /// @dev fallback eliminates the need to include function sig\n fallback (bytes calldata input) external returns (bytes memory) {\n decodeFallbackAndInvoke(input);\n }\n\n /// @dev this function serves (@todo will serve*) exactly the same as invoke(Invocation[] memory invocations),\n /// but includes all the logic to handle the highly packed calldata\n function decodeFallbackAndInvoke(bytes calldata input) private {\n uint ptr;\n uint len = input.length;\n \n for(ptr; ptr < len;) {\n uint8 action = toUint8(input[ptr:ptr+1]);\n ptr += 1;\n\n // solidity doesn't like evaluating bytes as enums :/ \n if(action == 1) { // DEPOSIT\n address account; address product; UFixed18 amount;\n (account, product, amount, ptr) = decodeAddressAddressAmount(input, ptr);\n\n depositTo(account, IProduct(product), amount);\n } else if (action == 2) { // WITHDRAW\n address receiver; address product; UFixed18 amount;\n (receiver, product, amount, ptr) = decodeAddressAddressAmount(input, ptr);\n\n collateral.withdrawFrom(msg.sender, receiver, IProduct(product), amount);\n } else if (action == 3) { // OPEN_TAKE\n address product; UFixed18 amount;\n (product, amount, ptr) = decodeAddressAmount(input, ptr);\n\n IProduct(product).openTakeFor(msg.sender, amount); \n } else if (action == 4) { // CLOSE_TAKE\n address product; UFixed18 amount;\n (product, amount, ptr) = decodeAddressAmount(input, ptr);\n\n IProduct(product).closeTakeFor(msg.sender, amount);\n } else if (action == 5) { // OPEN_MAKE \n address product; UFixed18 amount;\n (product, amount, ptr) = decodeAddressAmount(input, ptr);\n\n IProduct(product).openMakeFor(msg.sender, amount);\n } else if (action == 6) { // CLOSE_MAKE\n address product; UFixed18 amount;\n (product, amount, ptr) = decodeAddressAmount(input, ptr);\n\n IProduct(product).closeMakeFor(msg.sender, amount);\n } else if (action == 7) { // CLAIM \n address product; uint256[] memory programIds;\n (product, programIds, ptr) = decodeProductPrograms(input, ptr);\n\n controller.incentivizer().claimFor(msg.sender, IProduct(product), programIds);\n } else if (action == 8) { // WRAP \n address receiver; UFixed18 amount;\n (receiver, amount, ptr) = decodeAddressAmount(input, ptr);\n\n wrap(receiver, amount);\n } else if (action == 9) { // UNWRAP\n address receiver; UFixed18 amount;\n (receiver, amount, ptr) = decodeAddressAmount(input, ptr);\n\n unwrap(receiver, amount);\n } else if (action == 10) { // WRAP_AND_DEPOSIT\n address account; address product; UFixed18 amount;\n (account, product, amount, ptr) = decodeAddressAddressAmount(input, ptr);\n \n wrapAndDeposit(account, IProduct(product), amount);\n } else if (action == 11) { // WITHDRAW_AND_UNWRAP\n address receiver; address product; UFixed18 amount;\n (receiver, product, amount, ptr) = decodeAddressAddressAmount(input, ptr);\n\n withdrawAndUnwrap(receiver, IProduct(product), amount);\n } else if (action == 12) { // VAULT_DEPOSIT\n address depositer; address vault; UFixed18 amount;\n (depositer, vault, amount, ptr) = decodeAddressAddressAmount(input, ptr);\n\n vaultDeposit(depositer, IPerennialVault(vault), amount);\n } else if (action == 13) { // VAULT_REDEEM\n address vault; UFixed18 shares;\n (vault, shares, ptr) = decodeAddressAmount(input, ptr);\n\n IPerennialVault(vault).redeem(shares, msg.sender);\n } else if (action == 14) { // VAULT_CLAIM\n address owner; address vault;\n (owner, vault, ptr) = decodeAddressAddress(input, ptr);\n\n IPerennialVault(vault).claim(owner);\n } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT \n address account; address vault; UFixed18 amount;\n (account, vault, amount, ptr) = decodeAddressAddressAmount(input, ptr);\n\n vaultWrapAndDeposit(account, IPerennialVault(vault), amount);\n }\n }\n }\n\n /// Example Calldata Structure\n /// let ptr\n /// [ptr(userLen), ptr+1:userLen(user registry # OR 20 byte address if userLen == 0)] => address user \n /// ptr += (userLen OR 20) + 1\n /// [ptr(prodcutLen), ptr+1:productLen(product registry # OR 20 byte address if prdoctLen == 0)] => address product\n /// ptr += (prodcutLen OR 20) + 1\n /// [ptr(amountLen), ptr:amountLen] => uint256 amount \n\n\n // ARGUMENT TYPE DECODING //\n\n function decodeAddressAddressAmount(bytes calldata input, uint ptr) private returns (address addr1, address addr2, UFixed18 amount, uint) {\n (addr1, ptr) = decodeAddress(input, ptr);\n (addr2, ptr) = decodeAddress(input, ptr);\n (amount, ptr) = decodeAmountUFixed18(input, ptr);\n\n return (addr1, addr2, amount, ptr);\n }\n\n function decodeAddressAmount(bytes calldata input, uint ptr) private returns (address addr1, UFixed18 amount, uint) {\n (addr1, ptr) = decodeAddress(input, ptr);\n (amount, ptr) = decodeAmountUFixed18(input, ptr);\n\n return(addr1, UFixed18(amount), ptr);\n }\n\n function decodeProductPrograms(bytes calldata input, uint ptr) private returns(address product, uint256[] memory programs, uint) {\n (product, ptr) = decodeAddress(input, ptr);\n (programs, ptr) = decodeUintArray(input, ptr);\n\n return(product, programs, ptr);\n }\n\n function decodeAddressAddress(bytes calldata input, uint ptr) private returns(address addr1, address addr2, uint) {\n (addr1, ptr) = decodeAddress(input, ptr);\n (addr2, ptr) = decodeAddress(input, ptr);\n\n return (addr1, addr2, ptr);\n }\n\n\n // INDIVIDUAL TYPE DECODING //\n\n function decodeAmountUFixed18(bytes calldata input, uint ptr) private returns (UFixed18 result, uint) {\n uint temp;\n (temp, ptr) = decodeUint(input, ptr);\n\n return(UFixed18.wrap(temp), ptr);\n }\n\n function decodeUint(bytes calldata input, uint ptr) private returns (uint result, uint) {\n uint8 len = toUint8(input[ptr:ptr+1]);\n ++ptr;\n\n result = bytesToUint(input[ptr:ptr+len]);\n ptr += len;\n\n return (result, ptr);\n }\n\n \n\n // function decodeUFixed18Array(bytes calldata input, uint ptr) private returns (UFixed18[] memory, uint) {\n // uint8 arrayLen = toUint8(input[ptr:ptr+1]);\n // ++ptr;\n\n // UFixed18[] memory result = new UFixed18[](arrayLen);\n // uint count = 0;\n // for(;count < arrayLen;) {\n // UFixed18 currUint;\n\n // (currUint, ptr) = decodeAmountUFixed18(input, ptr);\n \n // result[count] = currUint;\n\n // ++count;\n // }\n\n // return (result, ptr);\n // }\n\n\n function decodeUintArray(bytes calldata input, uint ptr) private returns (uint256[] memory, uint) {\n uint8 arrayLen = toUint8(input[ptr:ptr+1]);\n ++ptr;\n\n uint256[] memory result = new uint256[](arrayLen);\n\n uint count = 0;\n for(;count < arrayLen;) {\n uint currUint;\n\n (currUint, ptr) = decodeUint(input, ptr);\n\n result[count] = currUint;\n\n ++count;\n }\n return (result, ptr);\n }\n\n function decodeAddress(bytes calldata input, uint ptr) private returns(address addr, uint) {\n uint8 addrLen = toUint8(input[ptr:ptr+1]);\n ptr += 1;\n\n // user is new to registry, add next 20 bytes as address to registry and return address\n if(addrLen == 0) {\n addr = bytesToAddress(input[ptr:ptr+20]);\n ptr += 20;\n\n setAddressCache(addr);\n\n } else {\n uint addrNonceLookup = bytesToUint(input[ptr:ptr+addrLen]);\n ptr += addrLen;\n\n addr = getAddressCacheSafe(addrNonceLookup);\n }\n\n return (addr, ptr);\n }\n\n function setAddressCache(address addr) private {\n ++addressNonce;\n addressCache[addressNonce] = addr;\n addressNonces[addr] = addressNonce;\n emit AddressAddedToCache(addr, addressNonce);\n }\n\n function getAddressCacheSafe(uint nonce) public returns (address addr){\n addr = addressCache[nonce];\n if(addr == address(0x0)) revert(\"Bad calldata, user !cached\");\n }\n\n // HELPER FUNCTIONS //\n \n // Unchecked force of 20 bytes into address\n // This is called in decodeAccount and decodeProduct which both only pass 20 byte slices \n function bytesToAddress(bytes memory input) private pure returns (address addr) {\n assembly {\n addr := mload(add(input, 20))\n } \n }\n\n // Unchecked implementation of GNSPS' standard BytesLib.sol\n function toUint8(bytes memory _b) internal pure returns (uint8 res) {\n assembly {\n res := mload(add(_b, 0x1))\n }\n }\n\n // loads arbitrarily-sized byte array into a uint unchecked\n function bytesToUint(bytes memory _b) private returns(uint256 res) {\n uint len = _b.length;\n\n assembly {\n res := mload(add(_b, 0x20))\n }\n\n if(res == 0x20) {\n return 0;\n }\n\n // readable right shift to change right padding of mload to left padding\n res >>= 256 - (len * 8);\n }\n\n}" + }, + "contracts/product/types/accumulator/AccountAccumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/types/Accumulator.sol\";\nimport \"../position/AccountPosition.sol\";\nimport \"./VersionedAccumulator.sol\";\n\n/// @dev AccountAccumulator type\nstruct AccountAccumulator {\n /// @dev latest version that the account was synced too\n uint256 latestVersion;\n}\nusing AccountAccumulatorLib for AccountAccumulator global;\n\n/**\n * @title AccountAccumulatorLib\n * @notice Library that manages syncing an account-level accumulator.\n */\nlibrary AccountAccumulatorLib {\n /**\n * @notice Syncs the account to oracle version `versionTo`\n * @param self The struct to operate on\n * @param global Pointer to global accumulator\n * @param position Pointer to global position\n * @param versionTo Oracle version to sync account to\n * @return value The value accumulated sync last sync\n */\n function syncTo(\n AccountAccumulator storage self,\n VersionedAccumulator storage global,\n AccountPosition storage position,\n uint256 versionTo\n ) internal returns (Accumulator memory value) {\n Accumulator memory valueAccumulated = global.valueAtVersion(versionTo)\n .sub(global.valueAtVersion(self.latestVersion));\n value = position.position.mul(valueAccumulated);\n self.latestVersion = versionTo;\n }\n}\n" + }, + "contracts/product/types/accumulator/VersionedAccumulator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/IProduct.sol\";\nimport \"../../../interfaces/types/Accumulator.sol\";\nimport \"../position/VersionedPosition.sol\";\n\n/// @dev VersionedAccumulator type\nstruct VersionedAccumulator {\n /// @dev Latest synced oracle version\n uint256 latestVersion;\n\n /// @dev Mapping of accumulator value at each settled oracle version\n mapping(uint256 => PackedAccumulator) _valueAtVersion;\n\n /// @dev Mapping of accumulator share at each settled oracle version\n mapping(uint256 => PackedAccumulator) _shareAtVersion;\n}\nusing VersionedAccumulatorLib for VersionedAccumulator global;\n\n/**\n * @title VersionedAccumulatorLib\n * @notice Library that manages global versioned accumulator state.\n * @dev Manages two accumulators: value and share. The value accumulator measures the change in position value\n * over time. The share accumulator measures the change in liquidity ownership over time (for tracking\n * incentivization rewards).\n *\n * Both accumulators are stamped for historical lookup anytime there is a global settlement, which services\n * the delayed-position accounting. It is not guaranteed that every version will have a value stamped, but\n * only versions when a settlement occurred are needed for this historical computation.\n */\nlibrary VersionedAccumulatorLib {\n /**\n * @notice Returns the stamped value accumulator at `oracleVersion`\n * @param self The struct to operate on\n * @param oracleVersion The oracle version to retrieve the value at\n * @return The stamped value accumulator at the requested version\n */\n function valueAtVersion(VersionedAccumulator storage self, uint256 oracleVersion) internal view returns (Accumulator memory) {\n return self._valueAtVersion[oracleVersion].unpack();\n }\n\n /**\n * @notice Returns the stamped share accumulator at `oracleVersion`\n * @param self The struct to operate on\n * @param oracleVersion The oracle version to retrieve the share at\n * @return The stamped share accumulator at the requested version\n */\n function shareAtVersion(VersionedAccumulator storage self, uint256 oracleVersion) internal view returns (Accumulator memory) {\n return self._shareAtVersion[oracleVersion].unpack();\n }\n\n /**\n * @notice Globally accumulates all value (position + funding) and share since last oracle update\n * @param self The struct to operate on\n * @param fundingFee The funding fee rate for the product\n * @param position Pointer to global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedFee The total fee accrued from accumulation\n */\n function accumulate(\n VersionedAccumulator storage self,\n UFixed18 fundingFee,\n VersionedPosition storage position,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal returns (UFixed18 accumulatedFee) {\n Position memory latestPosition = position.positionAtVersion(latestOracleVersion.version);\n\n // accumulate funding\n Accumulator memory accumulatedPosition;\n (accumulatedPosition, accumulatedFee) =\n _accumulateFunding(fundingFee, latestPosition, latestOracleVersion, toOracleVersion);\n\n // accumulate position\n accumulatedPosition = accumulatedPosition.add(\n _accumulatePosition(latestPosition, latestOracleVersion, toOracleVersion));\n\n // accumulate position fee\n (Accumulator memory accumulatedPositionFee, UFixed18 protocolPositionFee) =\n _accumulatePositionFee(latestPosition, position.pre, latestOracleVersion);\n accumulatedPosition = accumulatedPosition.add(accumulatedPositionFee);\n accumulatedFee = accumulatedFee.add(protocolPositionFee);\n\n // accumulate share\n Accumulator memory accumulatedShare =\n _accumulateShare(latestPosition, latestOracleVersion, toOracleVersion);\n\n // save update\n self._valueAtVersion[toOracleVersion.version] = valueAtVersion(self, latestOracleVersion.version)\n .add(accumulatedPosition)\n .pack();\n self._shareAtVersion[toOracleVersion.version] = shareAtVersion(self, latestOracleVersion.version)\n .add(accumulatedShare)\n .pack();\n self.latestVersion = toOracleVersion.version;\n }\n\n /**\n * @notice Globally accumulates all funding since last oracle update\n * @dev If an oracle version is skipped due to no pre positions, funding will continue to be\n * pegged to the price of the last snapshotted oracleVersion until a new one is accumulated.\n * This is an acceptable approximation.\n * @param fundingFee The funding fee rate for the product\n * @param latestPosition The latest global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedFunding The total amount accumulated from funding\n * @return accumulatedFee The total fee accrued from funding accumulation\n */\n function _accumulateFunding(\n UFixed18 fundingFee,\n Position memory latestPosition,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) private view returns (Accumulator memory accumulatedFunding, UFixed18 accumulatedFee) {\n if (_product().closed()) return (Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO), UFixed18Lib.ZERO);\n if (latestPosition.taker.isZero()) return (Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO), UFixed18Lib.ZERO);\n if (latestPosition.maker.isZero()) return (Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO), UFixed18Lib.ZERO);\n\n uint256 elapsed = toOracleVersion.timestamp - latestOracleVersion.timestamp;\n\n UFixed18 takerNotional = Fixed18Lib.from(latestPosition.taker).mul(latestOracleVersion.price).abs();\n UFixed18 socializedNotional = takerNotional.mul(latestPosition.socializationFactor());\n\n Fixed18 rateAccumulated = _product().rate(latestPosition)\n .mul(Fixed18Lib.from(UFixed18Lib.from(elapsed)));\n Fixed18 fundingAccumulated = rateAccumulated.mul(Fixed18Lib.from(socializedNotional));\n accumulatedFee = fundingAccumulated.abs().mul(fundingFee);\n\n Fixed18 fundingAccumulatedWithoutFee = Fixed18Lib.from(\n fundingAccumulated.sign(),\n fundingAccumulated.abs().sub(accumulatedFee)\n );\n\n bool makerPaysFunding = fundingAccumulated.sign() < 0;\n accumulatedFunding.maker = (makerPaysFunding ? fundingAccumulated : fundingAccumulatedWithoutFee)\n .div(Fixed18Lib.from(latestPosition.maker));\n accumulatedFunding.taker = (makerPaysFunding ? fundingAccumulatedWithoutFee : fundingAccumulated)\n .div(Fixed18Lib.from(latestPosition.taker)).mul(Fixed18Lib.NEG_ONE);\n }\n\n /**\n * @notice Globally accumulates position PNL since last oracle update\n * @param latestPosition The latest global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedPosition The total amount accumulated from position PNL\n */\n function _accumulatePosition(\n Position memory latestPosition,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) private view returns (Accumulator memory accumulatedPosition) {\n if (_product().closed()) return Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO);\n if (latestPosition.taker.isZero()) return Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO);\n if (latestPosition.maker.isZero()) return Accumulator(Fixed18Lib.ZERO, Fixed18Lib.ZERO);\n\n Fixed18 oracleDelta = toOracleVersion.price.sub(latestOracleVersion.price);\n Fixed18 totalTakerDelta = oracleDelta.mul(Fixed18Lib.from(latestPosition.taker));\n Fixed18 socializedTakerDelta = totalTakerDelta.mul(Fixed18Lib.from(latestPosition.socializationFactor()));\n\n accumulatedPosition.maker = socializedTakerDelta.div(Fixed18Lib.from(latestPosition.maker)).mul(Fixed18Lib.NEG_ONE);\n accumulatedPosition.taker = socializedTakerDelta.div(Fixed18Lib.from(latestPosition.taker));\n }\n\n /**\n * @notice Globally accumulates position fees since last oracle update\n * @dev Position fees are calculated based on the price at `latestOracleVersion` as that is the price used to\n * calculate the user's fee total. In the event that settlement is occurring over multiple oracle versions\n * (i.e. from a -> b -> c) it is safe to use the latestOracleVersion because in the a -> b case, a is always\n * b - 1, and in the b -> c case the `PrePosition` is always empty so this is skipped.\n * @param latestPosition The latest global position\n * @param pre The global pre-position\n * @param latestOracleVersion The latest oracle version\n * @return accumulatedPosition The total amount accumulated from position PNL\n * @return fee The position fee that is retained by the protocol and product\n */\n function _accumulatePositionFee(\n Position memory latestPosition,\n PrePosition memory pre,\n IOracleProvider.OracleVersion memory latestOracleVersion\n ) private view returns (Accumulator memory accumulatedPosition, UFixed18 fee) {\n if (pre.isEmpty()) return (accumulatedPosition, fee);\n\n Position memory positionFee = pre.computeFee(latestOracleVersion);\n Position memory protocolFee = positionFee.mul(_product().positionFee());\n positionFee = positionFee.sub(protocolFee);\n fee = protocolFee.sum();\n\n // If there are makers to distribute the taker's position fee to, distribute. Otherwise give it to the protocol\n if (!latestPosition.maker.isZero()) {\n accumulatedPosition.maker = Fixed18Lib.from(positionFee.taker.div(latestPosition.maker));\n } else {\n fee = fee.add(positionFee.taker);\n }\n\n // If there are takers to distribute the maker's position fee to, distribute. Otherwise give it to the protocol\n if (!latestPosition.taker.isZero()) {\n accumulatedPosition.taker = Fixed18Lib.from(positionFee.maker.div(latestPosition.taker));\n } else {\n fee = fee.add(positionFee.maker);\n }\n }\n\n /**\n * @notice Globally accumulates position's share of the total market since last oracle update\n * @dev This is used to compute incentivization rewards based on market participation\n * @param latestPosition The latest global position\n * @param latestOracleVersion The oracle version to accumulate from\n * @param toOracleVersion The oracle version to accumulate to\n * @return accumulatedShare The total share amount accumulated per position\n */\n function _accumulateShare(\n Position memory latestPosition,\n IOracleProvider.OracleVersion memory latestOracleVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) private pure returns (Accumulator memory accumulatedShare) {\n uint256 elapsed = toOracleVersion.timestamp - latestOracleVersion.timestamp;\n\n accumulatedShare.maker = latestPosition.maker.isZero() ?\n Fixed18Lib.ZERO :\n Fixed18Lib.from(UFixed18Lib.from(elapsed).div(latestPosition.maker));\n accumulatedShare.taker = latestPosition.taker.isZero() ?\n Fixed18Lib.ZERO :\n Fixed18Lib.from(UFixed18Lib.from(elapsed).div(latestPosition.taker));\n }\n\n function _product() private view returns (IProduct) {\n return IProduct(address(this));\n }\n}\n" + }, + "contracts/product/types/position/AccountPosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/IProduct.sol\";\nimport \"../../../interfaces/types/PrePosition.sol\";\n\n/// @dev AccountPosition type\nstruct AccountPosition {\n /// @dev The current settled position of the account\n Position position;\n\n /// @dev The current position delta pending-settlement\n PrePosition pre;\n\n /// @dev Whether the account is currently locked for liquidation\n bool liquidation;\n}\nusing AccountPositionLib for AccountPosition global;\n\n/**\n * @title AccountPositionLib\n * @notice Library that manages an account-level position.\n */\nlibrary AccountPositionLib {\n /**\n * @notice Settled the account's position to oracle version `toOracleVersion`\n * @param self The struct to operate on\n * @param toOracleVersion The oracle version to accumulate to\n */\n function settle(\n AccountPosition storage self,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal {\n bool settled;\n (self.position, settled) = self.position.settled(self.pre, toOracleVersion);\n if (settled) {\n delete self.pre;\n self.liquidation = false;\n }\n }\n\n /**\n * @notice Returns the current maintenance requirement for the account\n * @dev Must be called from a valid product to get the proper maintenance value\n * @param self The struct to operate on\n * @return Current maintenance requirement for the account\n */\n function maintenance(AccountPosition storage self) internal view returns (UFixed18) {\n return _maintenance(self.position);\n }\n\n /**\n * @notice Returns the maintenance requirement after the next oracle version settlement\n * @dev Includes the current pending-settlement position delta, assumes no price change\n * @param self The struct to operate on\n * @return Next maintenance requirement for the account\n */\n function maintenanceNext(AccountPosition storage self) internal view returns (UFixed18) {\n return _maintenance(self.position.next(self.pre));\n }\n\n /**\n * @notice Returns the maintenance requirement for a given `position`\n * @dev Internal helper\n * @param position The position to compete the maintenance requirement for\n * @return Next maintenance requirement for the account\n */\n function _maintenance(Position memory position) private view returns (UFixed18) {\n IProduct product = IProduct(address(this));\n Fixed18 oraclePrice = product.currentVersion().price;\n UFixed18 notionalMax = Fixed18Lib.from(position.max()).mul(oraclePrice).abs();\n return notionalMax.mul(product.maintenance());\n }\n\n /**\n * @notice Returns whether an account is completely closed, i.e. no position or pre-position\n * @param self The struct to operate on\n * @return Whether the account is closed\n */\n function isClosed(AccountPosition memory self) internal pure returns (bool) {\n return self.pre.isEmpty() && self.position.isEmpty();\n }\n\n /**\n * @notice Returns whether an account has opened position on both sides of the market (maker vs taker)\n * @dev Used to verify the invariant that a single account can only have a position on one side of the\n * market at a time\n * @param self The struct to operate on\n * @return Whether the account is currently doubled sided\n */\n function isDoubleSided(AccountPosition storage self) internal view returns (bool) {\n bool makerEmpty = self.position.maker.isZero() && self.pre.openPosition.maker.isZero() && self.pre.closePosition.maker.isZero();\n bool takerEmpty = self.position.taker.isZero() && self.pre.openPosition.taker.isZero() && self.pre.closePosition.taker.isZero();\n\n return !makerEmpty && !takerEmpty;\n }\n\n /**\n * @notice Returns whether the account's pending-settlement delta closes more position than is open\n * @dev Used to verify the invariant that an account cannot settle into having a negative position\n * @param self The struct to operate on\n * @return Whether the account is currently over closed\n */\n function isOverClosed(AccountPosition storage self) internal view returns (bool) {\n Position memory nextOpen = self.position.add(self.pre.openPosition);\n\n return self.pre.closePosition.maker.gt(nextOpen.maker) || self.pre.closePosition.taker.gt(nextOpen.taker);\n }\n}\n" + }, + "contracts/product/types/position/VersionedPosition.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"../../../interfaces/types/PrePosition.sol\";\nimport \"../../../interfaces/types/PackedPosition.sol\";\n\n//// @dev VersionedPosition type\nstruct VersionedPosition {\n /// @dev Mapping of global position at each version\n mapping(uint256 => PackedPosition) _positionAtVersion;\n\n /// @dev Current global pending-settlement position delta\n PrePosition pre;\n}\nusing VersionedPositionLib for VersionedPosition global;\n\n/**\n * @title VersionedPositionLib\n * @notice Library that manages global position state.\n * @dev Global position state is used to compute utilization rate and socialization, and to account for and\n * distribute fees globally.\n *\n * Positions are stamped for historical lookup anytime there is a global settlement, which services\n * the delayed-position accounting. It is not guaranteed that every version will have a value stamped, but\n * only versions when a settlement occurred are needed for this historical computation.\n */\nlibrary VersionedPositionLib {\n /**\n * @notice Returns the current global position\n * @return Current global position\n */\n function positionAtVersion(VersionedPosition storage self, uint256 oracleVersion) internal view returns (Position memory) {\n return self._positionAtVersion[oracleVersion].unpack();\n }\n\n /**\n * @notice Settled the global position to oracle version `toOracleVersion`\n * @param self The struct to operate on\n * @param latestVersion The latest settled oracle version\n * @param toOracleVersion The oracle version to settle to\n */\n function settle(\n VersionedPosition storage self,\n uint256 latestVersion,\n IOracleProvider.OracleVersion memory toOracleVersion\n ) internal {\n (Position memory newPosition, bool settled) =\n positionAtVersion(self, latestVersion).settled(self.pre, toOracleVersion);\n\n self._positionAtVersion[toOracleVersion.version] = newPosition.pack();\n if (settled) delete self.pre;\n }\n}\n" + }, + "contracts/product/UParamProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"../controller/UControllerProvider.sol\";\nimport \"../interfaces/IParamProvider.sol\";\nimport \"../interfaces/IProduct.sol\";\nimport \"../interfaces/types/PendingFeeUpdates.sol\";\n\n/**\n * @title UParamProvider\n * @notice Library for manage storing, surfacing, and upgrading a product's parameters.\n * @dev Uses an unstructured storage pattern to store the parameters which allows this\n provider to be safely used with upgradeable contracts. For certain paramters, a\n staged update pattern is used.\n */\nabstract contract UParamProvider is IParamProvider, UControllerProvider {\n /**\n * @notice Initializes the contract state\n * @param maintenance_ product maintenance ratio\n * @param fundingFee_ product funding fee\n * @param makerFee_ product maker fee\n * @param takerFee_ product taker fee\n * @param makerLimit_ product maker limit\n * @param utilizationCurve_ utilization curve definition\n */\n // solhint-disable-next-line func-name-mixedcase\n function __UParamProvider__initialize(\n UFixed18 maintenance_,\n UFixed18 fundingFee_,\n UFixed18 makerFee_,\n UFixed18 takerFee_,\n UFixed18 positionFee_,\n UFixed18 makerLimit_,\n JumpRateUtilizationCurve memory utilizationCurve_\n ) internal onlyInitializer {\n _updateMaintenance(maintenance_);\n _updateFundingFee(fundingFee_);\n _updateMakerFee(makerFee_);\n _updateTakerFee(takerFee_);\n _updatePositionFee(positionFee_);\n _updateMakerLimit(makerLimit_);\n _updateUtilizationCurve(utilizationCurve_);\n }\n\n /// @dev The maintenance value\n UFixed18Storage private constant _maintenance = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.maintenance\"));\n function maintenance() public view returns (UFixed18) { return _maintenance.read(); }\n\n /// @dev The funding fee value\n UFixed18Storage private constant _fundingFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.fundingFee\"));\n function fundingFee() public view returns (UFixed18) { return _fundingFee.read(); }\n\n /// @dev The maker fee value\n UFixed18Storage private constant _makerFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.makerFee\"));\n function makerFee() public view returns (UFixed18) { return _makerFee.read(); }\n\n /// @dev The taker fee value\n UFixed18Storage private constant _takerFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.takerFee\"));\n function takerFee() public view returns (UFixed18) { return _takerFee.read(); }\n\n /// @dev The positon fee share value\n UFixed18Storage private constant _positionFee = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.positionFee\"));\n function positionFee() public view returns (UFixed18) { return _positionFee.read(); }\n\n /// @dev The maker limit value\n UFixed18Storage private constant _makerLimit = UFixed18Storage.wrap(keccak256(\"equilibria.perennial.UParamProvider.makerLimit\"));\n function makerLimit() public view returns (UFixed18) { return _makerLimit.read(); }\n\n /// @dev The JumpRateUtilizationCurve params\n JumpRateUtilizationCurveStorage private constant _utilizationCurve =\n JumpRateUtilizationCurveStorage.wrap(keccak256(\"equilibria.perennial.UParamProvider.jumpRateUtilizationCurve\"));\n function utilizationCurve() public view returns (JumpRateUtilizationCurve memory) { return _utilizationCurve.read(); }\n\n /// @dev The pending fee updates value\n PendingFeeUpdatesStorage private constant _pendingFeeUpdates =\n PendingFeeUpdatesStorage.wrap(keccak256(\"equilibria.perennial.UParamProvider.pendingFeeUpdates\"));\n function pendingFeeUpdates() public view returns (PendingFeeUpdates memory) { return _pendingFeeUpdates.read(); }\n\n /**\n * @notice Updates the maintenance to `newMaintenance`\n * @param newMaintenance new maintenance value\n */\n function _updateMaintenance(UFixed18 newMaintenance) private {\n _maintenance.store(newMaintenance);\n emit MaintenanceUpdated(newMaintenance, _productVersion());\n }\n\n /**\n * @notice Updates the maintenance to `newMaintenance`\n * @dev only callable by product owner\n * @param newMaintenance new maintenance value\n */\n function updateMaintenance(UFixed18 newMaintenance) external onlyProductOwner settleProduct {\n _updateMaintenance(newMaintenance);\n }\n\n /**\n * @notice Updates the funding fee to `newFundingFee`\n * @param newFundingFee new funding fee value\n */\n function _updateFundingFee(UFixed18 newFundingFee) private {\n if (newFundingFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _fundingFee.store(newFundingFee);\n emit FundingFeeUpdated(newFundingFee, _productVersion());\n }\n\n /**\n * @notice Updates the funding fee to `newFundingFee`\n * @dev only callable by product owner\n * @param newFundingFee new funding fee value\n */\n function updateFundingFee(UFixed18 newFundingFee) external onlyProductOwner settleProduct {\n _updateFundingFee(newFundingFee);\n }\n\n /**\n * @notice Updates the maker fee to `newMakerFee`\n * @param newMakerFee new maker fee value\n */\n function _updateMakerFee(UFixed18 newMakerFee) private {\n if (newMakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _makerFee.store(newMakerFee);\n emit MakerFeeUpdated(newMakerFee, _productVersion());\n }\n\n /**\n * @notice Updates the pending maker fee to `newMakerFee`\n * @param newMakerFee new maker fee value\n */\n function _updatePendingMakerFee(UFixed18 newMakerFee) private {\n if (newMakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n PendingFeeUpdates memory pendingFees_ = pendingFeeUpdates();\n pendingFees_.updateMakerFee(newMakerFee);\n _pendingFeeUpdates.store(pendingFees_);\n emit PendingMakerFeeUpdated(newMakerFee);\n }\n\n /**\n * @notice Updates the maker fee to `newMakerFee`\n * @dev only callable by product owner\n * @param newMakerFee new maker fee value\n */\n function updateMakerFee(UFixed18 newMakerFee) external onlyProductOwner settleProduct {\n if (!_noPendingPositions()) {\n _updatePendingMakerFee(newMakerFee);\n } else {\n _updateMakerFee(newMakerFee);\n }\n }\n\n /**\n * @notice Updates the taker fee to `newTakerFee`\n * @param newTakerFee new taker fee value\n */\n function _updateTakerFee(UFixed18 newTakerFee) private {\n if (newTakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _takerFee.store(newTakerFee);\n emit TakerFeeUpdated(newTakerFee, _productVersion());\n }\n\n /**\n * @notice Updates the pending taker fee to `newTakerFee`\n * @param newTakerFee new taker fee value\n */\n function _updatePendingTakerFee(UFixed18 newTakerFee) private {\n if (newTakerFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n PendingFeeUpdates memory pendingFees_ = pendingFeeUpdates();\n pendingFees_.updateTakerFee(newTakerFee);\n _pendingFeeUpdates.store(pendingFees_);\n emit PendingTakerFeeUpdated(newTakerFee);\n }\n\n /**\n * @notice Updates the taker fee to `newTakerFee`\n * @dev only callable by product owner\n * @param newTakerFee new taker fee value\n */\n function updateTakerFee(UFixed18 newTakerFee) external onlyProductOwner settleProduct {\n if (!_noPendingPositions()) {\n _updatePendingTakerFee(newTakerFee);\n } else {\n _updateTakerFee(newTakerFee);\n }\n }\n\n /**\n * @notice Updates the position fee to `newPositionFee`\n * @param newPositionFee new position fee value\n */\n function _updatePositionFee(UFixed18 newPositionFee) private {\n if (newPositionFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n _positionFee.store(newPositionFee);\n emit PositionFeeUpdated(newPositionFee, _productVersion());\n }\n\n /**\n * @notice Updates the pending position fee to `newPositionFee`\n * @param newPositionFee new position fee value\n */\n function _updatePendingPositionFee(UFixed18 newPositionFee) private {\n if (newPositionFee.gt(UFixed18Lib.ONE)) revert ParamProviderInvalidParamValue();\n PendingFeeUpdates memory pendingFees_ = pendingFeeUpdates();\n pendingFees_.updatePositionFee(newPositionFee);\n _pendingFeeUpdates.store(pendingFees_);\n emit PendingPositionFeeUpdated(newPositionFee);\n }\n\n /**\n * @notice Updates the position fee to `newPositionFee`\n * @dev only callable by product owner\n * @param newPositionFee new position fee value\n */\n function updatePositionFee(UFixed18 newPositionFee) external onlyProductOwner settleProduct {\n if (!_noPendingPositions()) {\n _updatePendingPositionFee(newPositionFee);\n } else {\n _updatePositionFee(newPositionFee);\n }\n }\n\n /**\n * @notice Updates the maker limit to `newMakerLimit`\n * @param newMakerLimit new maker limit value\n */\n function _updateMakerLimit(UFixed18 newMakerLimit) private {\n _makerLimit.store(newMakerLimit);\n emit MakerLimitUpdated(newMakerLimit, _productVersion());\n }\n\n /**\n * @notice Updates the maker limit to `newMakerLimit`\n * @dev only callable by product owner\n * @param newMakerLimit new maker limit value\n */\n function updateMakerLimit(UFixed18 newMakerLimit) external onlyProductOwner settleProduct {\n _updateMakerLimit(newMakerLimit);\n }\n\n /**\n * @notice Updates the utilization curve to `newUtilizationCurve`\n * @param newUtilizationCurve new utilization curve value\n */\n function _updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) private {\n _utilizationCurve.store(newUtilizationCurve);\n emit JumpRateUtilizationCurveUpdated(newUtilizationCurve, _productVersion());\n }\n\n /**\n * @notice Updates the utilization curve to `newUtilizationCurve`\n * @dev only callable by product owner\n * @param newUtilizationCurve new utilization curve value\n */\n function updateUtilizationCurve(JumpRateUtilizationCurve calldata newUtilizationCurve) external onlyProductOwner settleProduct {\n _updateUtilizationCurve(newUtilizationCurve);\n }\n\n function _settleFeeUpdates() internal {\n PendingFeeUpdates memory pendingFeeUpdates_ = pendingFeeUpdates();\n if (!pendingFeeUpdates_.hasUpdates()) return;\n if (pendingFeeUpdates_.makerFeeUpdated) _updateMakerFee(pendingFeeUpdates_.makerFee());\n if (pendingFeeUpdates_.takerFeeUpdated) _updateTakerFee(pendingFeeUpdates_.takerFee());\n if (pendingFeeUpdates_.positionFeeUpdated) _updatePositionFee(pendingFeeUpdates_.positionFee());\n\n pendingFeeUpdates_.clear();\n _pendingFeeUpdates.store(pendingFeeUpdates_);\n }\n\n function _productVersion() private view returns (uint256) {\n // If this product is being constructed then return 0\n if (!Address.isContract(address(this))) return 0;\n return IProduct(address(this)).latestVersion();\n }\n\n /**\n * @notice Checks whether the Product's `pre` position is empty\n * @return Whether or not the pre position is empty\n */\n function _noPendingPositions() private view returns (bool) {\n return IProduct(address(this)).pre().isEmpty();\n }\n\n /// @dev Only allow the Product's coordinator owner to call\n modifier onlyProductOwner {\n uint256 coordinatorId = controller().coordinatorFor(IProduct(address(this)));\n if (controller().owner(coordinatorId) != msg.sender) revert NotOwnerError(coordinatorId);\n\n _;\n }\n\n /// @dev Settles the product\n modifier settleProduct {\n IProduct(address(this)).settle();\n\n _;\n }\n}\n" + }, + "contracts/product/UPayoffProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"@equilibria/root/control/unstructured/UInitializable.sol\";\nimport \"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\";\nimport \"@equilibria/root/storage/UStorage.sol\";\nimport \"../interfaces/IPayoffProvider.sol\";\nimport \"../interfaces/types/PayoffDefinition.sol\";\n\n/**\n * @title UPayoffProvider\n * @notice Library for manage storing, surfacing, and upgrading a payoff provider.\n * @dev Uses an unstructured storage pattern to store the oracle address and payoff definition which allows this\n provider to be safely used with upgradeable contracts.\n */\nabstract contract UPayoffProvider is IPayoffProvider, UInitializable {\n /// @dev The oracle contract address\n AddressStorage private constant _oracle =\n AddressStorage.wrap(keccak256(\"equilibria.perennial.UPayoffProvider.oracle\"));\n function oracle() public view returns (IOracleProvider) { return IOracleProvider(_oracle.read()); }\n\n /// @dev Payoff definition struct\n PayoffDefinitionStorage private constant _payoffDefinition =\n PayoffDefinitionStorage.wrap(keccak256(\"equilibria.perennial.UPayoffProvider.payoffDefinition\"));\n function payoffDefinition() public view returns (PayoffDefinition memory) { return _payoffDefinition.read(); }\n\n /**\n * @notice Initializes the contract state\n * @param oracle_ Oracle address\n * @param payoffDefinition_ Payoff provider\n */\n // solhint-disable-next-line func-name-mixedcase\n function __UPayoffProvider__initialize(IOracleProvider oracle_, PayoffDefinition calldata payoffDefinition_) internal onlyInitializer {\n _updateOracle(address(oracle_), 0);\n\n if (!payoffDefinition_.valid()) revert PayoffProviderInvalidPayoffDefinitionError();\n _payoffDefinition.store(payoffDefinition_);\n }\n\n /**\n * @notice Returns the current oracle version transformed by the payoff definition\n * @return Current oracle version transformed by the payoff definition\n */\n function currentVersion() public view returns (IOracleProvider.OracleVersion memory) {\n return _transform(oracle().currentVersion());\n }\n\n /**\n * @notice Returns the oracle version at `oracleVersion` transformed by the payoff definition\n * @param oracleVersion Oracle version to return for\n * @return Oracle version at `oracleVersion` with price transformed by payoff function\n */\n function atVersion(uint256 oracleVersion) public view returns (IOracleProvider.OracleVersion memory) {\n return _transform(oracle().atVersion(oracleVersion));\n }\n\n /**\n * @notice Updates oracle to newOracle address\n * @param newOracle New oracle address\n * @param oracleVersion Oracle version of update\n */\n function _updateOracle(address newOracle, uint256 oracleVersion) internal {\n if (!Address.isContract(newOracle)) revert PayoffProviderInvalidOracle();\n _oracle.store(newOracle);\n\n emit OracleUpdated(newOracle, oracleVersion);\n }\n\n /**\n * @notice Hook to call sync() on the oracle provider and transform the resulting oracle version\n */\n function _sync() internal returns (IOracleProvider.OracleVersion memory) {\n return _transform(oracle().sync());\n }\n\n /**\n * @notice Returns the transformed oracle version\n * @param oracleVersion Oracle version to transform\n * @return Transformed oracle version\n */\n function _transform(IOracleProvider.OracleVersion memory oracleVersion)\n internal view virtual returns (IOracleProvider.OracleVersion memory) {\n oracleVersion.price = payoffDefinition().transform(oracleVersion.price);\n return oracleVersion;\n }\n}\n" + }, + "contracts/test/TestnetBatcher.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\nimport \"./TestnetReserve.sol\";\n\ncontract TestnetBatcher is IBatcher {\n IEmptySetReserve public RESERVE;\n Token6 public USDC;\n Token18 public DSU;\n\n constructor(IEmptySetReserve reserve_, Token6 usdc_, Token18 dsu_) {\n RESERVE = reserve_;\n USDC = usdc_;\n DSU = dsu_;\n\n USDC.approve(address(RESERVE));\n DSU.approve(address(RESERVE));\n }\n\n function totalBalance() external pure returns (UFixed18) {\n return UFixed18Lib.MAX;\n }\n\n // Passthrough to Reserve\n function wrap(UFixed18 amount, address to) external {\n USDC.pull(msg.sender, amount, true);\n RESERVE.mint(amount);\n DSU.push(to, amount);\n\n emit Wrap(to, amount);\n }\n\n // Passthrough to Reserve\n function unwrap(UFixed18 amount, address to) external {\n DSU.pull(msg.sender, amount);\n RESERVE.redeem(amount);\n USDC.push(to, amount);\n\n emit Unwrap(to, amount);\n }\n\n // No-op\n function rebalance() external pure {\n return;\n }\n}\n" + }, + "contracts/test/TestnetDSU.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\ncontract TestnetDSU is ERC20, ERC20Burnable {\n uint256 private constant LIMIT = 1_000_000e18;\n\n address public minter;\n\n error TestnetDSUNotMinterError();\n error TestnetDSUOverLimitError();\n\n event TestnetDSUMinterUpdated(address indexed newMinter);\n\n constructor(address _minter) ERC20(\"Digital Standard Unit\", \"DSU\") {\n minter = _minter;\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n if (amount > LIMIT) revert TestnetDSUOverLimitError();\n\n _mint(account, amount);\n }\n\n function updateMinter(address newMinter) external onlyMinter {\n minter = newMinter;\n\n emit TestnetDSUMinterUpdated(newMinter);\n }\n\n modifier onlyMinter() {\n if (msg.sender != minter) revert TestnetDSUNotMinterError();\n _;\n }\n}\n" + }, + "contracts/test/TestnetProductProvider.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\";\nimport \"../interfaces/IContractPayoffProvider.sol\";\n\ncontract TestnetContractPayoffProvider is IContractPayoffProvider {\n function payoff(Fixed18 price) public pure returns (Fixed18) {\n return price.mul(price);\n }\n}\n" + }, + "contracts/test/TestnetReserve.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/token/types/Token6.sol\";\n\ncontract TestnetReserve is IEmptySetReserve {\n Token18 public immutable DSU; // solhint-disable-line var-name-mixedcase\n Token6 public immutable USDC; // solhint-disable-line var-name-mixedcase\n\n constructor(Token18 dsu_, Token6 usdc_) {\n DSU = dsu_;\n USDC = usdc_;\n }\n\n function mint(UFixed18 amount) external {\n USDC.pull(msg.sender, amount, true);\n ERC20PresetMinterPauser(Token18.unwrap(DSU)).mint(msg.sender, UFixed18.unwrap(amount));\n\n uint256 pulledAmount = Math.ceilDiv(UFixed18.unwrap(amount), 1e12);\n emit Mint(msg.sender, UFixed18.unwrap(amount), pulledAmount);\n }\n\n function redeem(UFixed18 amount) external {\n DSU.pull(msg.sender, amount);\n ERC20Burnable(Token18.unwrap(DSU)).burn(UFixed18.unwrap(amount));\n USDC.push(msg.sender, amount, true);\n\n uint256 pushedAmount = UFixed18.unwrap(amount) / 1e12;\n emit Redeem(msg.sender, UFixed18.unwrap(amount), pushedAmount);\n }\n\n function debt(address) external pure returns (UFixed18) {\n return UFixed18Lib.ZERO;\n }\n\n function repay(address, UFixed18) external pure {\n return;\n }\n}\n" + }, + "contracts/test/TestnetUSDC.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\ncontract TestnetUSDC is ERC20, ERC20Burnable {\n // solhint-disable-next-line no-empty-blocks\n constructor() ERC20(\"USD Coin\", \"USDC\") { }\n\n function decimals() override public pure returns (uint8) {\n return 6;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n }\n}\n" + }, + "contracts/test/TestnetVault.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.15;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@equilibria/root/token/types/Token18.sol\";\nimport \"@equilibria/root/number/types/UFixed18.sol\";\nimport { IPerennialVault } from \"../interfaces/IMultiInvoker.sol\";\n\ncontract TestnetVault is ERC20, IPerennialVault {\n Token18 public immutable asset;\n mapping(address => UFixed18) public claimable;\n\n uint256 private _version;\n\n constructor(Token18 _asset) ERC20(\"TestnetVaultToken\", \"TVT\") {\n asset = _asset;\n }\n\n function deposit(UFixed18 assets, address account) external {\n asset.pull(msg.sender, assets);\n\n _mint(account, UFixed18.unwrap(assets));\n\n emit Deposit(msg.sender, account, _version, assets);\n }\n\n function redeem(UFixed18 shares, address account) external {\n _burn(account, UFixed18.unwrap(shares));\n\n claimable[account] = claimable[account].add(shares);\n\n emit Redemption(msg.sender, account, _version, shares);\n }\n\n function claim(address owner) external {\n UFixed18 claimAmount = claimable[owner];\n claimable[owner] = UFixed18Lib.ZERO;\n asset.push(owner, claimAmount);\n\n emit Claim(msg.sender, owner, claimAmount);\n }\n\n function _incrementVersion() external {\n _version += 1;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/packages/perennial/test/integration/helpers/setupHelpers.ts b/packages/perennial/test/integration/helpers/setupHelpers.ts index 9d3b29b2..4287eb8b 100644 --- a/packages/perennial/test/integration/helpers/setupHelpers.ts +++ b/packages/perennial/test/integration/helpers/setupHelpers.ts @@ -35,6 +35,8 @@ import { MultiInvoker__factory, IEmptySetReserve, IEmptySetReserve__factory, + MultiInvokerRollup, + MultiInvokerRollup__factory, } from '../../../types/generated' import { ChainlinkContext } from './chainlinkHelpers' import { createPayoffDefinition } from '../../../../common/testutil/types' @@ -74,6 +76,7 @@ export interface InstanceVars { productBeacon: IBeacon productImpl: Product multiInvoker: MultiInvoker + multiInvokerRollup: MultiInvokerRollup incentivizer: Incentivizer lens: PerennialLens batcher: Batcher @@ -154,6 +157,20 @@ export async function deployProtocol(): Promise { const multiInvoker = await new MultiInvoker__factory(owner).attach(multiInvokerProxy.address) await multiInvoker.initialize() + const multiInvokerRollupImpl = await new MultiInvokerRollup__factory(owner).deploy( + usdc.address, + batcher.address, + reserve.address, + controllerProxy.address, + ) + const multiInvokerRollupProxy = await new TransparentUpgradeableProxy__factory(owner).deploy( + multiInvokerRollupImpl.address, + proxyAdmin.address, + [], + ) + const multiInvokerRollup = await new MultiInvokerRollup__factory(owner).attach(multiInvokerRollupProxy.address) + await multiInvokerRollup.initialize() + // Params - TODO: finalize before launch await controller.updatePauser(pauser.address) await controller.updateCoordinatorTreasury(0, treasuryA.address) @@ -194,6 +211,7 @@ export async function deployProtocol(): Promise { productBeacon, productImpl, multiInvoker, + multiInvokerRollup, incentivizer, collateral, lens, diff --git a/packages/perennial/test/integration/multiinvoker/multiinvoker.test.ts b/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts similarity index 97% rename from packages/perennial/test/integration/multiinvoker/multiinvoker.test.ts rename to packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts index 7f247587..211d49d7 100644 --- a/packages/perennial/test/integration/multiinvoker/multiinvoker.test.ts +++ b/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts @@ -138,7 +138,10 @@ describe('MultiInvoker', () => { }) it('performs a WRAP_AND_DEPOSIT and OPEN_MAKE chain', async () => { - const { user, multiInvoker, batcher, collateral, usdc } = instanceVars + const { user, multiInvoker, batcher, collateral, usdc, dsu } = instanceVars + + // Ensure this works without a DSU aproval + await dsu.connect(user).approve(multiInvoker.address, 0) await expect(multiInvoker.connect(user).invoke([actions.WRAP_AND_DEPOSIT, actions.OPEN_MAKE])) .to.emit(usdc, 'Transfer') @@ -221,7 +224,10 @@ describe('MultiInvoker', () => { }) it('performs a WRAP_AND_DEPOSIT and OPEN_TAKE chain', async () => { - const { user, userB, multiInvoker, batcher, collateral, usdc } = instanceVars + const { user, userB, multiInvoker, batcher, collateral, usdc, dsu } = instanceVars + + // Ensure this works without a DSU aproval + await dsu.connect(user).approve(multiInvoker.address, 0) await depositTo(instanceVars, userB, product, amount.mul(2)) await product.connect(userB).openMake(position.mul(2)) @@ -315,7 +321,7 @@ describe('MultiInvoker', () => { }) it('performs WITHDRAW_AND_UNWRAP', async () => { - const { user, multiInvoker, batcher, usdc, collateral, reserve } = instanceVars + const { user, multiInvoker, batcher, usdc, collateral, reserve, dsu } = instanceVars // Load the Reserve with some USDC await usdc.connect(user).approve(batcher.address, constants.MaxUint256) @@ -325,6 +331,9 @@ describe('MultiInvoker', () => { // Deposit the collateral to withdraw await multiInvoker.connect(user).invoke([actions.DEPOSIT]) + // Ensure this works without a DSU aproval + await dsu.connect(user).approve(multiInvoker.address, 0) + await expect(multiInvoker.connect(user).invoke([actions.WITHDRAW_AND_UNWRAP])) .to.emit(collateral, 'Withdrawal') .withArgs(user.address, product.address, amount) @@ -405,6 +414,9 @@ describe('MultiInvoker', () => { it('performs a VAULT_WRAP_AND_DEPOSIT action', async () => { const { user, multiInvoker, dsu, usdc, batcher } = instanceVars + // Ensure this works without a DSU aproval + await dsu.connect(user).approve(multiInvoker.address, 0) + await expect(multiInvoker.connect(user).invoke([actions.VAULT_WRAP_AND_DEPOSIT])) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvoker.address, 10000e6) diff --git a/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts b/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts new file mode 100644 index 00000000..009b3947 --- /dev/null +++ b/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts @@ -0,0 +1,567 @@ +import { TransactionRequest } from '@ethersproject/abstract-provider' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { expect } from 'chai' +import { BigNumber, BigNumberish, constants, utils } from 'ethers' +import { + MultiInvokerRollup__factory, + Product, + TestnetVault, + TestnetVault__factory, + MultiInvokerRollup, +} from '../../../types/generated' +import { IMultiInvokerRollup } from '../../../types/generated/contracts/interfaces/IMultiInvokerRollup' +import { buildInvokerActions, InvokerAction, buildInvokerActionRollup, buildAllActionsRollup } from '../../util' + +import { + InstanceVars, + deployProtocol, + createProduct, + createIncentiveProgram, + depositTo, + INITIAL_VERSION, +} from '../helpers/setupHelpers' + +describe('MultiInvokerRollup', () => { + let instanceVars: InstanceVars + + beforeEach(async () => { + instanceVars = await deployProtocol() + instanceVars.controller.updateMultiInvoker(instanceVars.multiInvokerRollup.address) + }) + + describe('#initialize', () => { + it('sets the correct contract addresses', async () => { + const { multiInvokerRollup, usdc, dsu, batcher, controller, collateral, reserve } = instanceVars + + expect((await multiInvokerRollup.USDC()).toLowerCase()).to.equal(usdc.address.toLowerCase()) + expect((await multiInvokerRollup.DSU()).toLowerCase()).to.equal(dsu.address.toLowerCase()) + expect((await multiInvokerRollup.batcher()).toLowerCase()).to.equal(batcher.address.toLowerCase()) + expect((await multiInvokerRollup.controller()).toLowerCase()).to.equal(controller.address.toLowerCase()) + expect((await multiInvokerRollup.collateral()).toLowerCase()).to.equal(collateral.address.toLowerCase()) + expect((await multiInvokerRollup.reserve()).toLowerCase()).to.equal(reserve.address.toLowerCase()) + }) + + it('sets the correct approvals', async () => { + const { multiInvokerRollup, usdc, dsu, batcher, collateral, reserve } = instanceVars + + expect(await dsu.allowance(multiInvokerRollup.address, collateral.address)).to.equal(constants.MaxUint256) + expect(await dsu.allowance(multiInvokerRollup.address, batcher.address)).to.equal(constants.MaxUint256) + expect(await dsu.allowance(multiInvokerRollup.address, reserve.address)).to.equal(constants.MaxUint256) + expect(await usdc.allowance(multiInvokerRollup.address, batcher.address)).to.equal(constants.MaxUint256) + expect(await usdc.allowance(multiInvokerRollup.address, reserve.address)).to.equal(constants.MaxUint256) + }) + + it('reverts if already initialized', async () => { + await expect(instanceVars.multiInvokerRollup.initialize()) + .to.be.revertedWithCustomError(instanceVars.multiInvokerRollup, 'UInitializableAlreadyInitializedError') + .withArgs(2) + }) + }) + + describe('common chains', async () => { + let product: Product + let actions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + let partialActions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + let customActions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + let position: BigNumber + let amount: BigNumber + let programs: number[] + let vault: TestnetVault + let vaultAmount: BigNumber + + beforeEach(async () => { + const { owner, user, dsu, usdc, usdcHolder, multiInvokerRollup } = instanceVars + + await usdc.connect(usdcHolder).transfer(user.address, 1_000_000e6) + await usdc.connect(user).approve(multiInvokerRollup.address, constants.MaxUint256) + await dsu.connect(user).approve(multiInvokerRollup.address, constants.MaxUint256) + + product = await createProduct(instanceVars) + const PROGRAM_ID = await createIncentiveProgram(instanceVars, product) + vault = await new TestnetVault__factory(owner).deploy(dsu.address) + await vault._incrementVersion() + + position = utils.parseEther('0.001') + amount = utils.parseEther('10000') + programs = [PROGRAM_ID.toNumber()] + vaultAmount = amount + actions = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position, + amount, + vaultAmount, + programs, + ) + + partialActions = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position.div(2), + amount.div(2), + vaultAmount, + programs, + ) + + customActions = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position, + utils.parseEther('2000000'), + vaultAmount, + programs, + ) + }) + + it('does nothing on NOOP', async () => { + const { user, multiInvokerRollup } = instanceVars + + await expect(await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.NOOP.payload))) + .to.not.be.reverted + + // const receipt = await tx.wait() + // expect(receipt.status).to.equal(1) + // expect(receipt.logs.length).to.equal(0) + }) + + it('calls the reserve directly if WRAP amount is greater than batcher balance', async () => { + const { user, dsu, usdc, usdcHolder, multiInvokerRollup, reserve } = instanceVars + + await usdc.connect(usdcHolder).transfer(user.address, 1_000_000e6) + + await expect( + await user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + customActions.WRAP.payload), + ), + ) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 2_000_000e6) + .to.emit(reserve, 'Mint') + .withArgs(multiInvokerRollup.address, utils.parseEther('2000000'), 2_000_000e6) + .to.emit(dsu, 'Transfer') + .withArgs(reserve.address, multiInvokerRollup.address, utils.parseEther('2000000')) + .to.emit(dsu, 'Transfer') + .withArgs(multiInvokerRollup.address, user.address, utils.parseEther('2000000')) + }) + + it('performs a WRAP, DEPOSIT, and OPEN_MAKE chain', async () => { + const { user, multiInvokerRollup, batcher, collateral, usdc } = instanceVars + + const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_MAKE])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 10000e6) + .to.emit(batcher, 'Wrap') + .withArgs(user.address, amount) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount) + .to.emit(product, 'MakeOpened') + .withArgs(user.address, INITIAL_VERSION, position) + }) + + it('performs a WRAP_AND_DEPOSIT and OPEN_MAKE chain', async () => { + const { user, multiInvokerRollup, batcher, collateral, usdc } = instanceVars + + const payload = buildAllActionsRollup(Object.values([actions.WRAP_AND_DEPOSIT, actions.OPEN_MAKE])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 10000e6) + .to.emit(batcher, 'Wrap') + .withArgs(multiInvokerRollup.address, amount) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount) + .to.emit(product, 'MakeOpened') + .withArgs(user.address, INITIAL_VERSION, position) + }) + + it('performs a DEPOSIT and OPEN_MAKE chain', async () => { + const { user, multiInvokerRollup, collateral } = instanceVars + + const payload = buildAllActionsRollup(Object.values([actions.DEPOSIT, actions.OPEN_MAKE])) + + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + + await expect(res) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount) + .to.emit(product, 'MakeOpened') + .withArgs(user.address, INITIAL_VERSION, position) + }) + + it('performs a CLOSE_MAKE, WITHDRAW, and CLAIM chain', async () => { + const { user, userB, multiInvokerRollup, incentivizer, chainlink, collateral } = instanceVars + + const payload1 = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_MAKE])) + + const res1 = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload1)) + + await expect(res1).to.not.be.reverted + await depositTo(instanceVars, userB, product, amount) + await product.connect(userB).openTake(position.div(2)) + + await chainlink.next() + await product.settle() + + await chainlink.next() + await chainlink.next() + await chainlink.next() + await product.settle() + + await product.connect(userB).closeTake(position.div(2)) + + const payload2 = buildAllActionsRollup( + Object.values([partialActions.CLOSE_MAKE, partialActions.WITHDRAW, actions.CLAIM]), + ) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + .to.emit(product, 'MakeClosed') + .withArgs(user.address, INITIAL_VERSION + 4, position.div(2)) + .to.emit(collateral, 'Withdrawal') + .withArgs(user.address, product.address, amount.div(2)) + .to.emit(incentivizer, 'Claim') + .withArgs(product.address, user.address, programs[0], '423010973936898252') + }) + + it('performs a CLOSE_MAKE and DEPOSIT', async () => { + const { user, multiInvokerRollup, chainlink, collateral } = instanceVars + + const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_MAKE])) + + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + + await chainlink.next() + + const payload2 = buildAllActionsRollup(Object.values([partialActions.CLOSE_MAKE, partialActions.DEPOSIT])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + .to.emit(product, 'MakeClosed') + .withArgs(user.address, INITIAL_VERSION + 1, position.div(2)) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount.div(2)) + }) + + it('performs a WRAP, DEPOSIT, and OPEN_TAKE chain', async () => { + const { user, userB, multiInvokerRollup, batcher, collateral, usdc } = instanceVars + + await depositTo(instanceVars, userB, product, amount.mul(2)) + await product.connect(userB).openMake(position.mul(2)) + + const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_TAKE])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 10000e6) + .to.emit(batcher, 'Wrap') + .withArgs(user.address, amount) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount) + .to.emit(product, 'TakeOpened') + .withArgs(user.address, INITIAL_VERSION, position) + }) + + it('performs a WRAP_AND_DEPOSIT and OPEN_TAKE chain', async () => { + const { user, userB, multiInvokerRollup, batcher, collateral, usdc } = instanceVars + + await depositTo(instanceVars, userB, product, amount.mul(2)) + await product.connect(userB).openMake(position.mul(2)) + + const payload = buildAllActionsRollup(Object.values([actions.WRAP_AND_DEPOSIT, actions.OPEN_TAKE])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 10000e6) + .to.emit(batcher, 'Wrap') + .withArgs(multiInvokerRollup.address, amount) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount) + .to.emit(product, 'TakeOpened') + .withArgs(user.address, INITIAL_VERSION, position) + }) + + it('performs a DEPOSIT and OPEN_TAKE chain', async () => { + const { user, userB, multiInvokerRollup, collateral } = instanceVars + + await depositTo(instanceVars, userB, product, amount.mul(2)) + await product.connect(userB).openMake(position.mul(2)) + + const payload = buildAllActionsRollup(Object.values([actions.DEPOSIT, actions.OPEN_TAKE])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount) + .to.emit(product, 'TakeOpened') + .withArgs(user.address, INITIAL_VERSION, position) + }) + + it('performs a CLOSE_TAKE and DEPOSIT chain', async () => { + const { user, userB, multiInvokerRollup, collateral, chainlink } = instanceVars + + await depositTo(instanceVars, userB, product, amount) + await product.connect(userB).openMake(position) + + const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_TAKE])) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + + await chainlink.next() + + const payload2 = buildAllActionsRollup(Object.values([partialActions.CLOSE_TAKE, partialActions.DEPOSIT])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + .to.emit(product, 'TakeClosed') + .withArgs(user.address, INITIAL_VERSION + 1, position.div(2)) + .to.emit(collateral, 'Deposit') + .withArgs(user.address, product.address, amount.div(2)) + }) + + it('performs a CLOSE_TAKE, WITHDRAW, and CLAIM chain', async () => { + const { user, userB, multiInvokerRollup, incentivizer, collateral, chainlink } = instanceVars + + await depositTo(instanceVars, userB, product, amount) + await product.connect(userB).openMake(position) + + const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_TAKE])) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + + await chainlink.next() + await product.settle() + + await chainlink.next() + await chainlink.next() + await chainlink.next() + await product.settle() + + const payload2 = buildAllActionsRollup( + Object.values([partialActions.CLOSE_TAKE, partialActions.WITHDRAW, actions.CLAIM]), + ) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + .to.emit(product, 'TakeClosed') + .withArgs(user.address, INITIAL_VERSION + 4, position.div(2)) + .to.emit(collateral, 'Withdrawal') + .withArgs(user.address, product.address, amount.div(2)) + .to.emit(incentivizer, 'Claim') + .withArgs(product.address, user.address, programs[0], '105752743484224563') + }) + + it('performs a WITHDRAW and UNWRAP chain', async () => { + const { user, multiInvokerRollup, batcher, usdc, collateral, reserve } = instanceVars + + // Load the Reserve with some USDC + await usdc.connect(user).approve(batcher.address, constants.MaxUint256) + await batcher.connect(user).wrap(amount, user.address) + await batcher.rebalance() + + // Deposit the collateral to withdraw + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload)) + + const payload = buildAllActionsRollup(Object.values([actions.WITHDRAW, actions.UNWRAP])) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(collateral, 'Withdrawal') + .withArgs(user.address, product.address, amount) + .to.emit(reserve, 'Redeem') + .withArgs(multiInvokerRollup.address, amount, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(reserve.address, multiInvokerRollup.address, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(multiInvokerRollup.address, user.address, 10000e6) + }) + + it('performs WITHDRAW_AND_UNWRAP', async () => { + const { user, multiInvokerRollup, batcher, usdc, collateral, reserve } = instanceVars + + // Load the Reserve with some USDC + await usdc.connect(user).approve(batcher.address, constants.MaxUint256) + await batcher.connect(user).wrap(amount, user.address) + await batcher.rebalance() + + // Deposit the collateral to withdraw + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload)) + + await expect( + user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW_AND_UNWRAP.payload), + ), + ) + .to.emit(collateral, 'Withdrawal') + .withArgs(user.address, product.address, amount) + .to.emit(reserve, 'Redeem') + .withArgs(multiInvokerRollup.address, amount, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(reserve.address, multiInvokerRollup.address, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(multiInvokerRollup.address, user.address, 10000e6) + }) + + it('Skips the reserve if batcher has enough USDC deposits', async () => { + const { user, multiInvokerRollup, batcher, usdc, usdcHolder } = instanceVars + + // Deposit USDC into the Batcher + const twowayiface = new utils.Interface(['function deposit(uint256)']) + await usdc.connect(usdcHolder).approve(batcher.address, constants.MaxUint256) + await usdcHolder.sendTransaction({ + to: batcher.address, + value: 0, + data: twowayiface.encodeFunctionData('deposit', [utils.parseEther('20000')]), + }) + + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)), + ) + .to.emit(batcher, 'Unwrap') + .withArgs(user.address, amount) + .to.emit(usdc, 'Transfer') + .withArgs(batcher.address, user.address, 10000e6) + }) + + it('performs a WRAP and VAULT_DEPOSIT chain', async () => { + const { user, multiInvokerRollup, dsu, batcher } = instanceVars + + const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.VAULT_DEPOSIT])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(batcher, 'Wrap') + .withArgs(user.address, amount) + .to.emit(dsu, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, vaultAmount) + .to.emit(dsu, 'Approval') + .withArgs(multiInvokerRollup.address, vault.address, vaultAmount) + .to.emit(vault, 'Deposit') + .withArgs(multiInvokerRollup.address, user.address, 1, vaultAmount) + + expect(await vault.balanceOf(user.address)).to.equal(vaultAmount) + expect(await vault.claimable(user.address)).to.equal(0) + }) + + it('performs a VAULT_REDEEM action', async () => { + const { user, multiInvokerRollup } = instanceVars + + const payload = buildAllActionsRollup(Object.values([actions.VAULT_DEPOSIT, actions.VAULT_REDEEM])) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(vault, 'Redemption') + .withArgs(multiInvokerRollup.address, user.address, 1, vaultAmount) + + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.claimable(user.address)).to.equal(vaultAmount) + }) + + it('performs a VAULT_CLAIM and UNWRAP chain', async () => { + const { user, multiInvokerRollup, dsu, reserve } = instanceVars + + const payload = buildAllActionsRollup( + Object.values([actions.VAULT_DEPOSIT, actions.VAULT_REDEEM, actions.VAULT_CLAIM, actions.UNWRAP]), + ) + + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + .to.emit(dsu, 'Transfer') + .withArgs(vault.address, user.address, vaultAmount) + .to.emit(vault, 'Claim') + .withArgs(multiInvokerRollup.address, user.address, vaultAmount) + .to.emit(reserve, 'Redeem') + .withArgs(multiInvokerRollup.address, amount, 10000e6) + + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.claimable(user.address)).to.equal(0) + }) + + it('performs a VAULT_WRAP_AND_DEPOSIT action', async () => { + const { user, multiInvokerRollup, dsu, usdc, batcher } = instanceVars + + await expect( + user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_WRAP_AND_DEPOSIT.payload), + ), + ) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 10000e6) + .to.emit(batcher, 'Wrap') + .withArgs(multiInvokerRollup.address, amount) + .to.emit(dsu, 'Approval') + .withArgs(multiInvokerRollup.address, vault.address, vaultAmount) + .to.emit(vault, 'Deposit') + .withArgs(multiInvokerRollup.address, user.address, 1, vaultAmount) + + expect(await vault.balanceOf(user.address)).to.equal(vaultAmount) + expect(await vault.claimable(user.address)).to.equal(0) + }) + + context('0 address batcher', () => { + beforeEach(async () => { + const { usdc, reserve, controller, multiInvokerRollup, owner, proxyAdmin } = instanceVars + const multiInvokerImpl = await new MultiInvokerRollup__factory(owner).deploy( + usdc.address, + constants.AddressZero, + reserve.address, + controller.address, + ) + + await proxyAdmin.upgrade(multiInvokerRollup.address, multiInvokerImpl.address) + }) + + it('calls the reserve directly on WRAP', async () => { + const { user, dsu, usdc, usdcHolder, multiInvokerRollup, reserve } = instanceVars + + await usdc.connect(usdcHolder).transfer(user.address, 1_000_000e6) + + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + customActions.WRAP.payload)), + ) + .to.emit(usdc, 'Transfer') + .withArgs(user.address, multiInvokerRollup.address, 2_000_000e6) + .to.emit(reserve, 'Mint') + .withArgs(multiInvokerRollup.address, utils.parseEther('2000000'), 2_000_000e6) + .to.emit(dsu, 'Transfer') + .withArgs(reserve.address, multiInvokerRollup.address, utils.parseEther('2000000')) + .to.emit(dsu, 'Transfer') + .withArgs(multiInvokerRollup.address, user.address, utils.parseEther('2000000')) + }) + + it('calls the reserve directly on UNWRAP', async () => { + const { user, multiInvokerRollup, batcher, usdc, reserve } = instanceVars + + // Load the Reserve with some USDC + await usdc.connect(user).approve(batcher.address, constants.MaxUint256) + await batcher.connect(user).wrap(amount, user.address) + await batcher.rebalance() + + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)), + ) + .to.emit(reserve, 'Redeem') + .withArgs(multiInvokerRollup.address, amount, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(reserve.address, multiInvokerRollup.address, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(multiInvokerRollup.address, user.address, 10000e6) + }) + }) + }) +}) + +export function buildTransactionRequest( + user: SignerWithAddress, + invoker: MultiInvokerRollup, + payload: string, +): TransactionRequest { + const txn: TransactionRequest = { + from: user.address, + to: invoker.address, + data: payload, + //gasLimit: 2e, + } + return txn +} diff --git a/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts b/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts new file mode 100644 index 00000000..094459ea --- /dev/null +++ b/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts @@ -0,0 +1,631 @@ +import { FakeContract, smock } from '@defi-wonderland/smock' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { assert, expect, use } from 'chai' +import HRE from 'hardhat' +import { BigNumber, BigNumberish, constants, utils } from 'ethers' + +import { + ICollateral, + IController, + IERC20, + MultiInvokerRollup, + MultiInvokerRollup__factory, + IProduct, + IIncentivizer, + IEmptySetReserve, + IBatcher, + TestnetVault, +} from '../../../types/generated' +import { IMultiInvokerRollup } from '../../../types/generated/contracts/interfaces/IMultiInvokerRollup' +import { InvokerAction, buildInvokerActionRollup, buildAllActionsRollup } from '../../util' +import { TransactionRequest } from '@ethersproject/abstract-provider' + +const { ethers } = HRE +use(smock.matchers) + +describe('MultiInvokerRollup', () => { + let owner: SignerWithAddress + let user: SignerWithAddress + let usdc: FakeContract + let dsu: FakeContract + let product: FakeContract + let collateral: FakeContract + let controller: FakeContract + let batcher: FakeContract + let incentivizer: FakeContract + let reserve: FakeContract + let vault: FakeContract + let multiInvokerRollup: MultiInvokerRollup + + beforeEach(async () => { + ;[owner, user] = await ethers.getSigners() + + usdc = await smock.fake('IERC20') + dsu = await smock.fake('IERC20') + collateral = await smock.fake('ICollateral') + batcher = await smock.fake('Batcher') + controller = await smock.fake('IController') + incentivizer = await smock.fake('IIncentivizer') + product = await smock.fake('IProduct') + reserve = await smock.fake('IEmptySetReserve') + vault = await smock.fake('TestnetVault') + + controller.collateral.returns(collateral.address) + controller.incentivizer.returns(incentivizer.address) + collateral.token.returns(dsu.address) + batcher.DSU.returns(dsu.address) + + multiInvokerRollup = await new MultiInvokerRollup__factory(owner).deploy( + usdc.address, + batcher.address, + reserve.address, + controller.address, + ) + + dsu.allowance.whenCalledWith(multiInvokerRollup.address, collateral.address).returns(0) + dsu.approve.whenCalledWith(collateral.address, 0).returns(true) + dsu.approve.whenCalledWith(collateral.address, ethers.constants.MaxUint256).returns(true) + + dsu.allowance.whenCalledWith(multiInvokerRollup.address, batcher.address).returns(0) + dsu.approve.whenCalledWith(batcher.address, 0).returns(true) + dsu.approve.whenCalledWith(batcher.address, ethers.constants.MaxUint256).returns(true) + + dsu.allowance.whenCalledWith(multiInvokerRollup.address, reserve.address).returns(0) + dsu.approve.whenCalledWith(reserve.address, 0).returns(true) + dsu.approve.whenCalledWith(reserve.address, ethers.constants.MaxUint256).returns(true) + dsu.balanceOf.whenCalledWith(batcher.address).returns(constants.MaxUint256) + + usdc.allowance.whenCalledWith(multiInvokerRollup.address, batcher.address).returns(0) + usdc.approve.whenCalledWith(batcher.address, 0).returns(true) + usdc.approve.whenCalledWith(batcher.address, ethers.constants.MaxUint256).returns(true) + + usdc.allowance.whenCalledWith(multiInvokerRollup.address, reserve.address).returns(0) + usdc.approve.whenCalledWith(reserve.address, 0).returns(true) + usdc.approve.whenCalledWith(reserve.address, ethers.constants.MaxUint256).returns(true) + usdc.balanceOf.whenCalledWith(batcher.address).returns(1_000_000e6) + + await multiInvokerRollup.initialize() + }) + + describe('#constructor', () => { + it('constructs correctly', async () => { + expect((await multiInvokerRollup.USDC()).toLowerCase()).to.equal(usdc.address.toLowerCase()) + expect((await multiInvokerRollup.DSU()).toLowerCase()).to.equal(dsu.address.toLowerCase()) + expect((await multiInvokerRollup.batcher()).toLowerCase()).to.equal(batcher.address.toLowerCase()) + expect((await multiInvokerRollup.controller()).toLowerCase()).to.equal(controller.address.toLowerCase()) + expect((await multiInvokerRollup.collateral()).toLowerCase()).to.equal(collateral.address.toLowerCase()) + expect((await multiInvokerRollup.reserve()).toLowerCase()).to.equal(reserve.address.toLowerCase()) + }) + }) + + describe('#initialize', () => { + it('initializes correctly', async () => { + expect(dsu.approve).to.be.calledWith(collateral.address, ethers.constants.MaxUint256) + expect(dsu.approve).to.be.calledWith(batcher.address, ethers.constants.MaxUint256) + expect(dsu.approve).to.be.calledWith(reserve.address, ethers.constants.MaxUint256) + expect(usdc.approve).to.be.calledWith(batcher.address, ethers.constants.MaxUint256) + expect(usdc.approve).to.be.calledWith(reserve.address, ethers.constants.MaxUint256) + }) + }) + + describe('#invoke', () => { + let actions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + let zeroAction: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + const amount = utils.parseEther('100') + const usdcAmount = 100e6 + const position = utils.parseEther('12') + const programs = [1, 2, 3] + const vaultAmount = utils.parseEther('567') + const vaultUSDCAmount = 567e6 + + beforeEach(() => { + actions = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position, + amount, + vaultAmount, + programs, + ) + + zeroAction = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position, + 0, + vaultAmount, + programs, + ) + + dsu.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, amount).returns(true) + usdc.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, usdcAmount).returns(true) + usdc.transfer.whenCalledWith(user.address, usdcAmount).returns(true) + usdc.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, vaultUSDCAmount).returns(true) + + // Vault deposits + dsu.allowance.whenCalledWith(multiInvokerRollup.address, vault.address).returns(0) + dsu.approve.whenCalledWith(vault.address, vaultAmount).returns(true) + dsu.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, vaultAmount).returns(true) + }) + + it('does nothing on NOOP action', async () => { + await expect(multiInvokerRollup.connect(user)).to.not.be.reverted + }) + + it('reverts with custom errors with bad calldata', async () => { + // store product in cache + await expect( + user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), + ), + ).to.not.be.reverted + + // cache index 3 is out of bounds, expect panic + const badAddressCachePld = '0x030103' + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, badAddressCachePld)), + ).to.be.revertedWithPanic() + + // length > 32 (33) for uint error + const badAmountPld = '0x030101213452434344' + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, badAmountPld)), + ).to.be.revertedWithCustomError(multiInvokerRollup, 'MultiInvokerRollupInvalidUint256LengthError') + }) + + it(`decodes 0 as a value on any action`, async () => { + usdc.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, 0).returns(true) + + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + zeroAction.WRAP.payload)), + ).to.not.be.reverted + expect(batcher.wrap).to.have.been.calledWith(BigNumber.from(0), user.address) + }) + + it('deposits on DEPOSIT action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload), + ) + + await expect(res).to.not.be.reverted + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) + }) + + it('withdraws on WITHDRAW action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW.payload), + ) + + await expect(res).to.not.be.reverted + expect(collateral.withdrawFrom).to.have.been.calledWith(user.address, user.address, product.address, amount) + }) + + it('opens a take position on OPEN_TAKE action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.OPEN_TAKE.payload), + ) + + await expect(res).to.not.be.reverted + expect(product.openTakeFor).to.have.been.calledWith(user.address, position) + }) + + it('closes a take position on CLOSE_TAKE action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CLOSE_TAKE.payload), + ) + + await expect(res).to.not.be.reverted + expect(product.closeTakeFor).to.have.been.calledWith(user.address, position) + }) + + it('opens a make position on OPEN_MAKE action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.OPEN_MAKE.payload), + ) + + await expect(res).to.not.be.reverted + expect(product.openMakeFor).to.have.been.calledWith(user.address, position) + }) + + it('closes a make position on CLOSE_MAKE action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CLOSE_MAKE.payload), + ) + + await expect(res).to.not.be.reverted + expect(product.closeMakeFor).to.have.been.calledWith(user.address, position) + }) + + it('claims incentive rewards on CLAIM action', async () => { + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CLAIM.payload)) + + await expect(res).to.not.be.reverted + expect(incentivizer.claimFor).to.have.been.calledWith(user.address, product.address, programs) + }) + + it('wraps USDC to DSU on WRAP action', async () => { + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP.payload)) + + await expect(res).to.not.be.reverted + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) + expect(batcher.wrap).to.have.been.calledWith(amount, user.address) + }) + + it('wraps USDC to DSU using RESERVE on WRAP action if amount is greater than batcher balance', async () => { + dsu.balanceOf.whenCalledWith(batcher.address).returns(0) + dsu.transfer.whenCalledWith(user.address, amount).returns(true) + + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP.payload)) + + await expect(res).to.not.be.reverted + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) + expect(reserve.mint).to.have.been.calledWith(amount) + expect(dsu.transfer).to.have.been.calledWith(user.address, amount) + }) + + it('unwraps DSU to USDC on UNWRAP action', async () => { + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)) + + await expect(res).to.not.be.reverted + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(batcher.unwrap).to.have.been.calledWith(amount, user.address) + }) + + it('unwraps DSU to USDC using RESERVE on UNWRAP action if amount is greater than batcher balance', async () => { + usdc.balanceOf.whenCalledWith(batcher.address).returns(0) + usdc.transfer.whenCalledWith(user.address, amount).returns(true) + + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)) + + await expect(res).to.not.be.reverted + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(reserve.redeem).to.have.been.calledWith(amount) + expect(usdc.transfer).to.have.been.calledWith(user.address, usdcAmount) + }) + + it('wraps USDC to DSU then deposits DSU on WRAP_AND_DEPOSIT action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), + ) + + await expect(res).to.not.be.reverted + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) + expect(batcher.wrap).to.have.been.calledWith(amount, multiInvokerRollup.address) + expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) + }) + + it('wraps USDC to DSU using RESERVE then deposits DSU on WRAP_AND_DEPOSIT action if amount is greater than batcher balance', async () => { + dsu.balanceOf.whenCalledWith(batcher.address).returns(0) + dsu.transfer.whenCalledWith(multiInvokerRollup.address, amount).returns(true) + + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), + ) + + await expect(res).to.not.be.reverted + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) + expect(reserve.mint).to.have.been.calledWith(amount) + expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) + }) + + it('withdraws then unwraps DSU to USDC on WITHDRAW_AND_UNWRAP action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW_AND_UNWRAP.payload), + ) + + await expect(res).to.not.be.reverted + expect(collateral.withdrawFrom).to.have.been.calledWith( + user.address, + multiInvokerRollup.address, + product.address, + amount, + ) + + expect(batcher.unwrap).to.have.been.calledWith(amount, user.address) + }) + + it('withdraws then unwraps DSU to USDC using RESERVE on WITHDRAW_AND_UNWRAP action if amount is greater than batcher balance', async () => { + usdc.balanceOf.whenCalledWith(batcher.address).returns(0) + + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW_AND_UNWRAP.payload), + ) + + await expect(res).to.not.be.reverted + expect(collateral.withdrawFrom).to.have.been.calledWith( + user.address, + multiInvokerRollup.address, + product.address, + amount, + ) + expect(reserve.redeem).to.have.been.calledWith(amount) + expect(usdc.transfer).to.have.been.calledWith(user.address, usdcAmount) + }) + + it('deposits to vault on VAULT_DEPOSIT action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_DEPOSIT.payload), + ) + + await expect(res).to.not.be.reverted + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, vaultAmount) + expect(dsu.approve).to.have.been.calledWith(vault.address, vaultAmount) + expect(vault.deposit).to.have.been.calledWith(vaultAmount, user.address) + }) + + it('redeems from vault on VAULT_REDEEM action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_REDEEM.payload), + ) + + await expect(res).to.not.be.reverted + expect(vault.redeem).to.have.been.calledWith(vaultAmount, user.address) + }) + + it('claims from vault on VAULT_CLAIM action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_CLAIM.payload), + ) + + await expect(res).to.not.be.reverted + expect(vault.claim).to.have.been.calledWith(user.address) + }) + + it('wraps USDC to DSU then deposits DSU to the vault on VAULT_WRAP_AND_DEPOSIT action', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_WRAP_AND_DEPOSIT.payload), + ) + + await expect(res).to.not.be.reverted + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, vaultUSDCAmount) + expect(batcher.wrap).to.have.been.calledWith(vaultAmount, multiInvokerRollup.address) + expect(dsu.approve).to.have.been.calledWith(vault.address, vaultAmount) + expect(vault.deposit).to.have.been.calledWith(vaultAmount, user.address) + }) + + it('performs a multi invoke', async () => { + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, buildAllActionsRollup(Object.values(actions))), + ) + + await expect(res).to.not.be.reverted + + // Deposit/Withdraw + expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) + expect(collateral.withdrawFrom).to.have.been.calledWith(user.address, user.address, product.address, amount) + + // Open/Close Positions + expect(product.openTakeFor).to.have.been.calledWith(user.address, position) + expect(product.closeTakeFor).to.have.been.calledWith(user.address, position) + expect(product.openMakeFor).to.have.been.calledWith(user.address, position) + expect(product.closeMakeFor).to.have.been.calledWith(user.address, position) + + // Claim + expect(incentivizer.claimFor).to.have.been.calledWith(user.address, product.address, programs) + + // Wrap/Unwrap + expect(batcher.wrap).to.have.been.calledWith(amount, user.address) + expect(batcher.unwrap).to.have.been.calledWith(amount, user.address) + + // Underlying Transfers + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) + + // Vault deposit + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, vaultAmount) + expect(dsu.approve).to.have.been.calledWith(vault.address, vaultAmount) + expect(vault.deposit).to.have.been.calledWith(vaultAmount, user.address) + + // Vault redeem + expect(vault.redeem).to.have.been.calledWith(vaultAmount, user.address) + + // Vault claim + expect(vault.claim).to.have.been.calledWith(user.address) + + // Vault wrap and deposit + expect(batcher.wrap).to.have.been.calledWith(vaultAmount, multiInvokerRollup.address) + }) + }) + + context('batcher address is 0', () => { + beforeEach(async () => { + multiInvokerRollup = await new MultiInvokerRollup__factory(owner).deploy( + usdc.address, + constants.AddressZero, + reserve.address, + controller.address, + ) + + dsu.allowance.whenCalledWith(multiInvokerRollup.address, collateral.address).returns(0) + dsu.approve.whenCalledWith(collateral.address, ethers.constants.MaxUint256).returns(true) + dsu.allowance.whenCalledWith(multiInvokerRollup.address, reserve.address).returns(0) + dsu.approve.whenCalledWith(reserve.address, ethers.constants.MaxUint256).returns(true) + + usdc.allowance.whenCalledWith(multiInvokerRollup.address, reserve.address).returns(0) + usdc.approve.whenCalledWith(reserve.address, ethers.constants.MaxUint256).returns(true) + + await multiInvokerRollup.initialize() + }) + + describe('#constructor', () => { + it('constructs correctly', async () => { + expect((await multiInvokerRollup.USDC()).toLowerCase()).to.equal(usdc.address.toLowerCase()) + expect((await multiInvokerRollup.DSU()).toLowerCase()).to.equal(dsu.address.toLowerCase()) + expect((await multiInvokerRollup.batcher()).toLowerCase()).to.equal(constants.AddressZero) + expect((await multiInvokerRollup.controller()).toLowerCase()).to.equal(controller.address.toLowerCase()) + expect((await multiInvokerRollup.collateral()).toLowerCase()).to.equal(collateral.address.toLowerCase()) + expect((await multiInvokerRollup.reserve()).toLowerCase()).to.equal(reserve.address.toLowerCase()) + }) + }) + + describe('#initialize', () => { + it('initializes correctly', async () => { + expect(dsu.approve).to.be.calledWith(collateral.address, ethers.constants.MaxUint256) + expect(dsu.approve).to.be.calledWith(reserve.address, ethers.constants.MaxUint256) + expect(usdc.approve).to.be.calledWith(reserve.address, ethers.constants.MaxUint256) + }) + }) + + describe('#invoke', () => { + let actions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + const amount = utils.parseEther('100') + const usdcAmount = 100e6 + const position = utils.parseEther('12') + const VaultAmount = utils.parseEther('567') + const programs = [1, 2, 3] + + beforeEach(() => { + actions = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position, + amount, + VaultAmount, + programs, + ) + dsu.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, amount).returns(true) + usdc.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, usdcAmount).returns(true) + usdc.transfer.whenCalledWith(user.address, usdcAmount).returns(true) + }) + + it('wraps USDC to DSU using RESERVE on WRAP action', async () => { + dsu.transfer.whenCalledWith(user.address, amount).returns(true) + + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP.payload)) + + await expect(res).to.not.be.reverted + // multiInvokerRollup.connect(user).invoke([actions.WRAP]) + expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) + expect(reserve.mint).to.have.been.calledWith(amount) + expect(dsu.transfer).to.have.been.calledWith(user.address, amount) + }) + + it('unwraps DSU to USDC using RESERVE on UNWRAP action', async () => { + usdc.transfer.whenCalledWith(user.address, amount).returns(true) + + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload), + ) + + await expect(res).to.not.be.reverted + + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(reserve.redeem).to.have.been.calledWith(amount) + expect(usdc.transfer).to.have.been.calledWith(user.address, usdcAmount) + }) + }) + }) + + context('performs actions using cache', () => { + describe('#constructor', () => { + it('constructs correctly', async () => { + expect((await multiInvokerRollup.USDC()).toLowerCase()).to.equal(usdc.address.toLowerCase()) + expect((await multiInvokerRollup.DSU()).toLowerCase()).to.equal(dsu.address.toLowerCase()) + expect((await multiInvokerRollup.batcher()).toLowerCase()).to.equal(batcher.address.toLowerCase()) + expect((await multiInvokerRollup.controller()).toLowerCase()).to.equal(controller.address.toLowerCase()) + expect((await multiInvokerRollup.collateral()).toLowerCase()).to.equal(collateral.address.toLowerCase()) + expect((await multiInvokerRollup.reserve()).toLowerCase()).to.equal(reserve.address.toLowerCase()) + }) + }) + + describe('#initialize', () => { + it('initializes correctly', async () => { + expect(dsu.approve).to.be.calledWith(collateral.address, ethers.constants.MaxUint256) + expect(dsu.approve).to.be.calledWith(batcher.address, ethers.constants.MaxUint256) + expect(dsu.approve).to.be.calledWith(reserve.address, ethers.constants.MaxUint256) + expect(usdc.approve).to.be.calledWith(batcher.address, ethers.constants.MaxUint256) + expect(usdc.approve).to.be.calledWith(reserve.address, ethers.constants.MaxUint256) + }) + }) + + describe('#invoke', () => { + let actions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + let actionsCached: { [action in InvokerAction]: { action: BigNumberish; payload: string } } + const amount = utils.parseEther('50') + const usdcAmount = 100e6 + const position = utils.parseEther('12') + const VaultAmount = utils.parseEther('567') + const programs = [1, 2, 3] + + beforeEach(() => { + actions = buildInvokerActionRollup( + BigNumber.from(0), + BigNumber.from(0), + BigNumber.from(0), + user.address, + product.address, + vault.address, + position, + amount, + VaultAmount, + programs, + ) + actionsCached = buildInvokerActionRollup( + BigNumber.from(1), + BigNumber.from(2), + BigNumber.from(0), + undefined, + undefined, + vault.address, + position, + amount, + VaultAmount, + programs, + ) + + dsu.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, amount).returns(true) + usdc.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, usdcAmount).returns(true) + usdc.transfer.whenCalledWith(user.address, usdcAmount).returns(true) + }) + + it('performs cached invoke on DEPOSIT', async () => { + // 1) set state caching + + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload)), + ).to.not.be.reverted + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) + + // assert caches set in 1st txn + expect(await multiInvokerRollup.connect(user).addressLookup(user.address)).to.eq(1) + expect(await multiInvokerRollup.connect(user).addressLookup(product.address)).to.eq(2) + + // 2) call contract with cached payload + + await expect( + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actionsCached.DEPOSIT.payload)), + ).to.not.be.reverted + expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) + expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) + }) + }) + }) +}) + +export function buildTransactionRequest( + user: SignerWithAddress, + invoker: MultiInvokerRollup, + payload: string, +): TransactionRequest { + const txn: TransactionRequest = { + from: user.address, + to: invoker.address, + data: payload, + gasLimit: 2.5e7, + } + return txn +} diff --git a/packages/perennial/test/util.ts b/packages/perennial/test/util.ts index b51754f4..72fff8b4 100644 --- a/packages/perennial/test/util.ts +++ b/packages/perennial/test/util.ts @@ -1,5 +1,6 @@ -import { constants, utils, BigNumberish } from 'ethers' -import { IMultiInvoker } from '../types/generated/contracts/interfaces/IMultiInvoker' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { constants, utils, BigNumberish, BigNumber } from 'ethers' +import { IMultiInvoker, MultiInvokerRollup } from '../types/generated' export type InvokerAction = | 'NOOP' @@ -103,3 +104,179 @@ export const buildInvokerActions = ({ }, } } + +export const buildAllActionsRollup = ( + actions: { + action: BigNumberish + payload: string + }[], + // actions: { + // action: InvokerAction + // userCache: BigNumber | null, + // productCache: BigNumber, + // userAddress?: string, + // productAddress?: string, + // position?: BigNumberish, + // amount?: BigNumberish, + // programs?: number[] + // }[] +): string => { + let pld = '' + + for (const a of actions) { + if (a.action == 'NOOP') { + continue + } + + pld += a.payload + } + + return pld +} + +export const buildInvokerActionRollup = ( + userCache: BigNumber, // BN(0) if not used + productCache: BigNumber, // BN(0) if not used + vaultCache: BigNumber, // BN(0) if not used + userAddress?: string, + productAddress?: string, + vaultAddress?: string, + position?: BigNumberish, + amount?: BigNumberish, + vaultAmount?: BigNumberish, + programs?: number[], +): { [action in InvokerAction]: { action: BigNumberish; payload: string } } => { + return { + NOOP: { + action: 0, + payload: '0x', + }, + DEPOSIT: { + action: 1, + // [userAddress productAddress amount] + payload: + '01' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(amount)), + }, + WITHDRAW: { + action: 2, + // [userAddress productAddress amount] + payload: + '02' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(amount)), + }, + OPEN_TAKE: { + action: 3, + // [productAddress position] + payload: '03' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + }, + CLOSE_TAKE: { + action: 4, + // [productAddress position] + payload: '04' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + }, + OPEN_MAKE: { + action: 5, + // [productAddress position] + payload: '05' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + }, + CLOSE_MAKE: { + action: 6, + // [productAddress position] + payload: '06' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + }, + CLAIM: { + action: 7, + // [productAddress programs] + payload: '07' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeProgramIds(programs!), + }, + WRAP: { + action: 8, + // [userAddress amount] + payload: '08' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeUint(BigNumber.from(amount)), + }, + UNWRAP: { + action: 9, + // [userAddress amount] + payload: '09' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeUint(BigNumber.from(amount)), + }, + WRAP_AND_DEPOSIT: { + action: 10, + // [userAddress, productAddress, amount] + payload: + '0A' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(amount)), + }, + WITHDRAW_AND_UNWRAP: { + action: 11, + // [userAddress, productAddress, amount] + payload: + '0B' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(amount)), + }, + VAULT_DEPOSIT: { + action: 12, + payload: + '0C' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + + encodeUint(BigNumber.from(vaultAmount)), + }, + VAULT_REDEEM: { + action: 13, + payload: '0D' + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + encodeUint(BigNumber.from(vaultAmount)), + }, + VAULT_CLAIM: { + action: 14, + payload: + '0E' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(vaultCache, vaultAddress), + }, + VAULT_WRAP_AND_DEPOSIT: { + action: 15, + payload: + '0F' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + + encodeUint(BigNumber.from(vaultAmount)), + }, + } +} + +export const encodeUint = (uint: BigNumber) => { + if (uint.eq(0)) return '0100' + return toHex((uint._hex.length - 2) / 2) + toHex(uint._hex) +} + +export const encodeAddressOrCacheIndex = ( + cacheIndex: BigNumber, // must not be null, default to BN(0) and pass address if user's first interaction with protocol + address?: string, +) => { + // include address if first interaction with the protocol, + // contract reads the next 20 bytes into an address when given an address length of 0 + if (address) return '00' + address.slice(2) + + // + return encodeUint(cacheIndex) +} + +export const encodeProgramIds = (programs: number[]) => { + let encoded = toHex(BigNumber.from(programs.length)) + + programs.forEach(program => { + encoded += encodeUint(BigNumber.from(program)) + }) + + return encoded +} + +function toHex(input: BigNumberish): string { + return BigNumber.from(input)._hex.slice(2) +} diff --git a/yarn.lock b/yarn.lock index 97689a4a..d5596d41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -136,28 +136,21 @@ "@0xsequence/transactions" "^0.43.20" "@0xsequence/utils" "^0.43.20" -"@babel/code-frame@7.12.11": +"@babel/code-frame@7.12.11", "@babel/code-frame@^7.0.0": version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": +"@babel/highlight@^7.10.4": version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz" integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== dependencies: "@babel/helper-validator-identifier" "^7.16.7" @@ -166,7 +159,7 @@ "@chainlink/contracts@0.5.1": version "0.5.1" - resolved "https://registry.yarnpkg.com/@chainlink/contracts/-/contracts-0.5.1.tgz#68e7447ba8c1eccfbb760bacc93aced2eef60945" + resolved "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.5.1.tgz" integrity sha512-3PDBJ38Sd6Ml9h7FNK/tZQti+kTCdXUq1qzE6E59CnlzycsV9ElPvf2hTvs9Mi9C6pEx2Mmw9yhZMfBktYUInQ== dependencies: "@eth-optimism/contracts" "^0.5.21" @@ -175,7 +168,7 @@ "@codechecks/client@^0.1.10": version "0.1.12" - resolved "https://registry.yarnpkg.com/@codechecks/client/-/client-0.1.12.tgz#519f11be8fcaa581c6ee8d5e8457e35bbbe5d9b1" + resolved "https://registry.npmjs.org/@codechecks/client/-/client-0.1.12.tgz" integrity sha512-2GHHvhO3kaOyxFXxOaiznlY8ARmz33/p+WQdhc2y6wzWw5eOl2wSwg1eZxx3LsWlAnB963Y4bd1YjZcGIhKRzA== dependencies: bluebird "^3.5.3" @@ -201,12 +194,12 @@ "@colors/colors@1.5.0": version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== "@defi-wonderland/smock@^2.3.4": version "2.3.4" - resolved "https://registry.yarnpkg.com/@defi-wonderland/smock/-/smock-2.3.4.tgz#2bfe7e19052140634b25db344d77de9b0ac7a96b" + resolved "https://registry.npmjs.org/@defi-wonderland/smock/-/smock-2.3.4.tgz" integrity sha512-VYJbsoCOdFRyGkAwvaQhQRrU6V8AjK3five8xdbo41DEE9n3qXzUNBUxyD9HhXB/dWWPFWT21IGw5Ztl6Qw3Ew== dependencies: "@nomicfoundation/ethereumjs-evm" "^1.0.0-rc.3" @@ -220,7 +213,7 @@ "@ensdomains/ens@^0.4.4": version "0.4.5" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + resolved "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz" integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== dependencies: bluebird "^3.5.2" @@ -231,12 +224,12 @@ "@ensdomains/resolver@^0.2.4": version "0.2.4" - resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + resolved "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz" integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== "@equilibria/emptyset-batcher@0.1.0": version "0.1.0" - resolved "https://registry.yarnpkg.com/@equilibria/emptyset-batcher/-/emptyset-batcher-0.1.0.tgz#2068d202d38614a337d115d4109f05cf72e48d09" + resolved "https://registry.npmjs.org/@equilibria/emptyset-batcher/-/emptyset-batcher-0.1.0.tgz" integrity sha512-joALMtS47fdXw9nvSO4gmmcsYvfErXlC92nYDGV2wRGqyUneOZKPVC1s0TctSBK/OeXJ+ielzXVLqB84H5PZKg== dependencies: "@equilibria/root" "0.1.5" @@ -244,7 +237,7 @@ "@equilibria/root@0.1.5": version "0.1.5" - resolved "https://registry.yarnpkg.com/@equilibria/root/-/root-0.1.5.tgz#f9fb606fed2d0f3d7426d37d7bc45f176b26f80e" + resolved "https://registry.npmjs.org/@equilibria/root/-/root-0.1.5.tgz" integrity sha512-K++w/DyJktl58dQe4P78K0dzduQe1CKPU+Z52DsISik99FN7OwdMTQZt1APpJfovfZh0focsHMnTiRpLmIti7Q== dependencies: "@openzeppelin/contracts" "4.6.0" @@ -258,14 +251,14 @@ "@equilibria/root@0.2.0": version "0.2.0" - resolved "https://registry.yarnpkg.com/@equilibria/root/-/root-0.2.0.tgz#0cad4d9f9b2872e4282166b950d85dbb20d27acf" + resolved "https://registry.npmjs.org/@equilibria/root/-/root-0.2.0.tgz" integrity sha512-5cfN7IyzkwgD3R9GovDoEXio21Fc15e5iuk7xcWuB5Ns9zBXYnhPFthtn8Y0JubIUvpENX1jqCz7VxfFgAZbJA== dependencies: "@openzeppelin/contracts" "4.6.0" "@eslint/eslintrc@^0.4.3": version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== dependencies: ajv "^6.12.4" @@ -280,7 +273,7 @@ "@eth-optimism/contracts@^0.5.21": version "0.5.39" - resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.5.39.tgz#a312a0a0b2d5853cd417c5e8969e87288e166fcb" + resolved "https://registry.npmjs.org/@eth-optimism/contracts/-/contracts-0.5.39.tgz" integrity sha512-u3UufuZFzgidRN2/cC3mhRxX+M6VsMV9tauIKu8D5pym5/UO4pZr85WP3KxHFfLh1i8zmkdj+pN/GRQsNYCqMg== dependencies: "@eth-optimism/core-utils" "0.12.0" @@ -289,7 +282,7 @@ "@eth-optimism/core-utils@0.12.0": version "0.12.0" - resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.12.0.tgz#6337e4599a34de23f8eceb20378de2a2de82b0ea" + resolved "https://registry.npmjs.org/@eth-optimism/core-utils/-/core-utils-0.12.0.tgz" integrity sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw== dependencies: "@ethersproject/abi" "^5.7.0" @@ -311,7 +304,7 @@ "@ethereum-waffle/chai@^3.4.4": version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.4.tgz#16c4cc877df31b035d6d92486dfdf983df9138ff" + resolved "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz" integrity sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g== dependencies: "@ethereum-waffle/provider" "^3.4.4" @@ -319,7 +312,7 @@ "@ethereum-waffle/compiler@^3.4.4": version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz#d568ee0f6029e68b5c645506079fbf67d0dfcf19" + resolved "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.4.tgz" integrity sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ== dependencies: "@resolver-engine/imports" "^0.3.3" @@ -336,7 +329,7 @@ "@ethereum-waffle/ens@^3.4.4": version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/ens/-/ens-3.4.4.tgz#db97ea2c9decbb70b9205d53de2ccbd6f3182ba1" + resolved "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.4.4.tgz" integrity sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg== dependencies: "@ensdomains/ens" "^0.4.4" @@ -345,7 +338,7 @@ "@ethereum-waffle/mock-contract@^3.4.4": version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz#fc6ffa18813546f4950a69f5892d4dd54b2c685a" + resolved "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.4.4.tgz" integrity sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA== dependencies: "@ethersproject/abi" "^5.5.0" @@ -353,7 +346,7 @@ "@ethereum-waffle/provider@^3.4.4": version "3.4.4" - resolved "https://registry.yarnpkg.com/@ethereum-waffle/provider/-/provider-3.4.4.tgz#398fc1f7eb91cc2df7d011272eacba8af0c7fffb" + resolved "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.4.tgz" integrity sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g== dependencies: "@ethereum-waffle/ens" "^3.4.4" @@ -364,7 +357,7 @@ "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" + resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz" integrity sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg== dependencies: "@ethersproject/address" ">=5.0.0-beta.128" @@ -377,24 +370,9 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abi@5.6.1", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.6.0": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.1.tgz#f7de888edeb56b0a657b672bdd1b3a1135cd14f7" - integrity sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w== - dependencies: - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.7.0": +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== dependencies: "@ethersproject/address" "^5.7.0" @@ -407,22 +385,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/abstract-provider@5.6.0", "@ethersproject/abstract-provider@^5", "@ethersproject/abstract-provider@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz#0c4ac7054650dbd9c476cf5907f588bbb6ef3061" - integrity sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/web" "^5.6.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5", "@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" + resolved "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz" integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== dependencies: "@ethersproject/bignumber" "^5.7.0" @@ -433,20 +398,9 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/web" "^5.7.0" -"@ethersproject/abstract-signer@5.6.0", "@ethersproject/abstract-signer@^5", "@ethersproject/abstract-signer@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz#9cd7ae9211c2b123a3b29bf47aab17d4d016e3e7" - integrity sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ== - dependencies: - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": +"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5", "@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" + resolved "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz" integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== dependencies: "@ethersproject/abstract-provider" "^5.7.0" @@ -455,20 +409,9 @@ "@ethersproject/logger" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/address@5.6.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.0.tgz#13c49836d73e7885fc148ad633afad729da25012" - integrity sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/rlp" "^5.6.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": +"@ethersproject/address@5.7.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + resolved "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz" integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== dependencies: "@ethersproject/bignumber" "^5.7.0" @@ -477,110 +420,47 @@ "@ethersproject/logger" "^5.7.0" "@ethersproject/rlp" "^5.7.0" -"@ethersproject/base64@5.6.0", "@ethersproject/base64@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.0.tgz#a12c4da2a6fb86d88563216b0282308fc15907c9" - integrity sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw== - dependencies: - "@ethersproject/bytes" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz" integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== dependencies: "@ethersproject/bytes" "^5.7.0" -"@ethersproject/basex@5.6.0", "@ethersproject/basex@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.6.0.tgz#9ea7209bf0a1c3ddc2a90f180c3a7f0d7d2e8a69" - integrity sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/properties" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz" integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/properties" "^5.7.0" -"@ethersproject/bignumber@5.6.0", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.0.tgz#116c81b075c57fa765a8f3822648cf718a8a0e26" - integrity sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - bn.js "^4.11.9" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": +"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.5.1", "@ethersproject/bignumber@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + resolved "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz" integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" bn.js "^5.2.1" -"@ethersproject/bignumber@^5.5.1": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.2.tgz#72a0717d6163fab44c47bcc82e0c550ac0315d66" - integrity sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw== - dependencies: - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@5.6.1", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.6.0", "@ethersproject/bytes@^5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7" - integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g== - dependencies: - "@ethersproject/logger" "^5.6.0" - -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz" integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/constants@5.6.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.0.tgz#55e3eb0918584d3acc0688e9958b0cedef297088" - integrity sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": +"@ethersproject/constants@5.7.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + resolved "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz" integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== dependencies: "@ethersproject/bignumber" "^5.7.0" -"@ethersproject/contracts@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.0.tgz#60f2cfc7addd99a865c6c8cfbbcec76297386067" - integrity sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw== - dependencies: - "@ethersproject/abi" "^5.6.0" - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/contracts@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" + resolved "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz" integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== dependencies: "@ethersproject/abi" "^5.7.0" @@ -594,23 +474,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/transactions" "^5.7.0" -"@ethersproject/hash@5.6.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.0.tgz#d24446a5263e02492f9808baa99b6e2b4c3429a2" - integrity sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA== - dependencies: - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": +"@ethersproject/hash@5.7.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + resolved "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz" integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== dependencies: "@ethersproject/abstract-signer" "^5.7.0" @@ -623,27 +489,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/hdnode@5.6.0", "@ethersproject/hdnode@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.6.0.tgz#9dcbe8d629bbbcf144f2cae476337fe92d320998" - integrity sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw== - dependencies: - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/basex" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/pbkdf2" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - "@ethersproject/signing-key" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/wordlists" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz" integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== dependencies: "@ethersproject/abstract-signer" "^5.7.0" @@ -659,28 +507,9 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/wordlists" "^5.7.0" -"@ethersproject/json-wallets@5.6.0", "@ethersproject/json-wallets@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz#4c2fc27f17e36c583e7a252fb938bc46f98891e5" - integrity sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ== - dependencies: - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/hdnode" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/pbkdf2" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - "@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" + resolved "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz" integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== dependencies: "@ethersproject/abstract-signer" "^5.7.0" @@ -697,104 +526,44 @@ aes-js "3.0.0" scrypt-js "3.0.1" -"@ethersproject/keccak256@5.6.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.0.tgz#fea4bb47dbf8f131c2e1774a1cecbfeb9d606459" - integrity sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w== - dependencies: - "@ethersproject/bytes" "^5.6.0" - js-sha3 "0.8.0" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": +"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + resolved "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz" integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== dependencies: "@ethersproject/bytes" "^5.7.0" js-sha3 "0.8.0" -"@ethersproject/logger@5.6.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a" - integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg== - -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": +"@ethersproject/logger@5.7.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + resolved "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz" integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== -"@ethersproject/networks@5.6.2", "@ethersproject/networks@^5.6.0": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.2.tgz#2bacda62102c0b1fcee408315f2bed4f6fbdf336" - integrity sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA== - dependencies: - "@ethersproject/logger" "^5.6.0" - "@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" + resolved "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz" integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/pbkdf2@5.6.0", "@ethersproject/pbkdf2@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz#04fcc2d7c6bff88393f5b4237d906a192426685a" - integrity sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/sha2" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz" integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/sha2" "^5.7.0" -"@ethersproject/properties@5.6.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.6.0.tgz#38904651713bc6bdd5bdd1b0a4287ecda920fa04" - integrity sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg== - dependencies: - "@ethersproject/logger" "^5.6.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": +"@ethersproject/properties@5.7.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + resolved "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz" integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.6.5": - version "5.6.5" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.5.tgz#aefecf78459817a323452e05a16d56afcf807e27" - integrity sha512-TRS+c2Ud+cMpWodmGAc9xbnYRPWzRNYt2zkCSnj58nJoamBQ6x4cUbBeo0lTC3y+6RDVIBeJv18OqsDbSktLVg== - dependencies: - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/basex" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.0" - "@ethersproject/rlp" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/web" "^5.6.0" - bech32 "1.1.4" - ws "7.4.6" - "@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.0": version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + resolved "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== dependencies: "@ethersproject/abstract-provider" "^5.7.0" @@ -818,71 +587,34 @@ bech32 "1.1.4" ws "7.4.6" -"@ethersproject/random@5.6.0", "@ethersproject/random@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.0.tgz#1505d1ab6a250e0ee92f436850fa3314b2cb5ae6" - integrity sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@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" + resolved "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz" integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/rlp@5.6.0", "@ethersproject/rlp@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.0.tgz#55a7be01c6f5e64d6e6e7edb6061aa120962a717" - integrity sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz" integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== dependencies: "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/sha2@5.6.0", "@ethersproject/sha2@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.6.0.tgz#364c4c11cc753bda36f31f001628706ebadb64d9" - integrity sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - hash.js "1.1.7" - "@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" + resolved "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz" 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.6.1", "@ethersproject/signing-key@^5.6.0": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.1.tgz#31b0a531520616254eb0465b9443e49515c4d457" - integrity sha512-XvqQ20DH0D+bS3qlrrgh+axRMth5kD1xuvqUQUTeezxUTXBOeR6hWz2/C6FBEu39FRytyybIWrYf7YLSAKr1LQ== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - bn.js "^4.11.9" - elliptic "6.5.4" - 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" + resolved "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz" integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== dependencies: "@ethersproject/bytes" "^5.7.0" @@ -892,21 +624,9 @@ elliptic "6.5.4" hash.js "1.1.7" -"@ethersproject/solidity@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.6.0.tgz#64657362a596bf7f5630bdc921c07dd78df06dc3" - integrity sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/sha2" "^5.6.0" - "@ethersproject/strings" "^5.6.0" - "@ethersproject/solidity@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" + resolved "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz" integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== dependencies: "@ethersproject/bignumber" "^5.7.0" @@ -916,42 +636,18 @@ "@ethersproject/sha2" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/strings@5.6.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.0.tgz#9891b26709153d996bf1303d39a7f4bc047878fd" - integrity sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": +"@ethersproject/strings@5.7.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + resolved "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz" 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.6.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.0.tgz#4b594d73a868ef6e1529a2f8f94a785e6791ae4e" - integrity sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg== - dependencies: - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/rlp" "^5.6.0" - "@ethersproject/signing-key" "^5.6.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== dependencies: "@ethersproject/address" "^5.7.0" @@ -964,48 +660,18 @@ "@ethersproject/rlp" "^5.7.0" "@ethersproject/signing-key" "^5.7.0" -"@ethersproject/units@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.6.0.tgz#e5cbb1906988f5740254a21b9ded6bd51e826d9c" - integrity sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw== - dependencies: - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/constants" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/units@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" + resolved "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz" integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== dependencies: "@ethersproject/bignumber" "^5.7.0" "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/wallet@5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.6.0.tgz#33d11a806d783864208f348709a5a3badac8e22a" - integrity sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg== - dependencies: - "@ethersproject/abstract-provider" "^5.6.0" - "@ethersproject/abstract-signer" "^5.6.0" - "@ethersproject/address" "^5.6.0" - "@ethersproject/bignumber" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/hdnode" "^5.6.0" - "@ethersproject/json-wallets" "^5.6.0" - "@ethersproject/keccak256" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/random" "^5.6.0" - "@ethersproject/signing-key" "^5.6.0" - "@ethersproject/transactions" "^5.6.0" - "@ethersproject/wordlists" "^5.6.0" - "@ethersproject/wallet@5.7.0": version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" + resolved "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz" integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== dependencies: "@ethersproject/abstract-provider" "^5.7.0" @@ -1024,20 +690,9 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/wordlists" "^5.7.0" -"@ethersproject/web@5.6.0", "@ethersproject/web@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.0.tgz#4bf8b3cbc17055027e1a5dd3c357e37474eaaeb8" - integrity sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg== - dependencies: - "@ethersproject/base64" "^5.6.0" - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz" integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== dependencies: "@ethersproject/base64" "^5.7.0" @@ -1046,20 +701,9 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/wordlists@5.6.0", "@ethersproject/wordlists@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.6.0.tgz#79e62c5276e091d8575f6930ba01a29218ded032" - integrity sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q== - dependencies: - "@ethersproject/bytes" "^5.6.0" - "@ethersproject/hash" "^5.6.0" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.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" + resolved "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz" integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== dependencies: "@ethersproject/bytes" "^5.7.0" @@ -1070,7 +714,7 @@ "@gar/promisify@^1.0.1": version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== "@graphql-typed-document-node/core@^3.1.1": @@ -1080,7 +724,7 @@ "@humanwhocodes/config-array@^0.5.0": version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz" integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== dependencies: "@humanwhocodes/object-schema" "^1.2.0" @@ -1089,17 +733,17 @@ "@humanwhocodes/object-schema@^1.2.0": version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@hutson/parse-repository-url@^3.0.0": version "3.0.2" - resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" + resolved "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== "@lerna/add@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/add/-/add-4.0.0.tgz#c36f57d132502a57b9e7058d1548b7a565ef183f" + resolved "https://registry.npmjs.org/@lerna/add/-/add-4.0.0.tgz" integrity sha512-cpmAH1iS3k8JBxNvnMqrGTTjbY/ZAiKa1ChJzFevMYY3eeqbvhsBKnBcxjRXtdrJ6bd3dCQM+ZtK+0i682Fhng== dependencies: "@lerna/bootstrap" "4.0.0" @@ -1115,7 +759,7 @@ "@lerna/bootstrap@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-4.0.0.tgz#5f5c5e2c6cfc8fcec50cb2fbe569a8c607101891" + resolved "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-4.0.0.tgz" integrity sha512-RkS7UbeM2vu+kJnHzxNRCLvoOP9yGNgkzRdy4UV2hNalD7EP41bLvRVOwRYQ7fhc2QcbhnKNdOBihYRL0LcKtw== dependencies: "@lerna/command" "4.0.0" @@ -1143,7 +787,7 @@ "@lerna/changed@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-4.0.0.tgz#b9fc76cea39b9292a6cd263f03eb57af85c9270b" + resolved "https://registry.npmjs.org/@lerna/changed/-/changed-4.0.0.tgz" integrity sha512-cD+KuPRp6qiPOD+BO6S6SN5cARspIaWSOqGBpGnYzLb4uWT8Vk4JzKyYtc8ym1DIwyoFXHosXt8+GDAgR8QrgQ== dependencies: "@lerna/collect-updates" "4.0.0" @@ -1153,7 +797,7 @@ "@lerna/check-working-tree@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-4.0.0.tgz#257e36a602c00142e76082a19358e3e1ae8dbd58" + resolved "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-4.0.0.tgz" integrity sha512-/++bxM43jYJCshBiKP5cRlCTwSJdRSxVmcDAXM+1oUewlZJVSVlnks5eO0uLxokVFvLhHlC5kHMc7gbVFPHv6Q== dependencies: "@lerna/collect-uncommitted" "4.0.0" @@ -1162,7 +806,7 @@ "@lerna/child-process@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-4.0.0.tgz#341b96a57dffbd9705646d316e231df6fa4df6e1" + resolved "https://registry.npmjs.org/@lerna/child-process/-/child-process-4.0.0.tgz" integrity sha512-XtCnmCT9eyVsUUHx6y/CTBYdV9g2Cr/VxyseTWBgfIur92/YKClfEtJTbOh94jRT62hlKLqSvux/UhxXVh613Q== dependencies: chalk "^4.1.0" @@ -1171,7 +815,7 @@ "@lerna/clean@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-4.0.0.tgz#8f778b6f2617aa2a936a6b5e085ae62498e57dc5" + resolved "https://registry.npmjs.org/@lerna/clean/-/clean-4.0.0.tgz" integrity sha512-uugG2iN9k45ITx2jtd8nEOoAtca8hNlDCUM0N3lFgU/b1mEQYAPRkqr1qs4FLRl/Y50ZJ41wUz1eazS+d/0osA== dependencies: "@lerna/command" "4.0.0" @@ -1185,7 +829,7 @@ "@lerna/cli@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-4.0.0.tgz#8eabd334558836c1664df23f19acb95e98b5bbf3" + resolved "https://registry.npmjs.org/@lerna/cli/-/cli-4.0.0.tgz" integrity sha512-Neaw3GzFrwZiRZv2g7g6NwFjs3er1vhraIniEs0jjVLPMNC4eata0na3GfE5yibkM/9d3gZdmihhZdZ3EBdvYA== dependencies: "@lerna/global-options" "4.0.0" @@ -1195,7 +839,7 @@ "@lerna/collect-uncommitted@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-4.0.0.tgz#855cd64612969371cfc2453b90593053ff1ba779" + resolved "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-4.0.0.tgz" integrity sha512-ufSTfHZzbx69YNj7KXQ3o66V4RC76ffOjwLX0q/ab//61bObJ41n03SiQEhSlmpP+gmFbTJ3/7pTe04AHX9m/g== dependencies: "@lerna/child-process" "4.0.0" @@ -1204,7 +848,7 @@ "@lerna/collect-updates@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-4.0.0.tgz#8e208b1bafd98a372ff1177f7a5e288f6bea8041" + resolved "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-4.0.0.tgz" integrity sha512-bnNGpaj4zuxsEkyaCZLka9s7nMs58uZoxrRIPJ+nrmrZYp1V5rrd+7/NYTuunOhY2ug1sTBvTAxj3NZQ+JKnOw== dependencies: "@lerna/child-process" "4.0.0" @@ -1215,7 +859,7 @@ "@lerna/command@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/command/-/command-4.0.0.tgz#991c7971df8f5bf6ae6e42c808869a55361c1b98" + resolved "https://registry.npmjs.org/@lerna/command/-/command-4.0.0.tgz" integrity sha512-LM9g3rt5FsPNFqIHUeRwWXLNHJ5NKzOwmVKZ8anSp4e1SPrv2HNc1V02/9QyDDZK/w+5POXH5lxZUI1CHaOK/A== dependencies: "@lerna/child-process" "4.0.0" @@ -1231,7 +875,7 @@ "@lerna/conventional-commits@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-4.0.0.tgz#660fb2c7b718cb942ead70110df61f18c6f99750" + resolved "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-4.0.0.tgz" integrity sha512-CSUQRjJHFrH8eBn7+wegZLV3OrNc0Y1FehYfYGhjLE2SIfpCL4bmfu/ViYuHh9YjwHaA+4SX6d3hR+xkeseKmw== dependencies: "@lerna/validation-error" "4.0.0" @@ -1248,7 +892,7 @@ "@lerna/create-symlink@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-4.0.0.tgz#8c5317ce5ae89f67825443bd7651bf4121786228" + resolved "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-4.0.0.tgz" integrity sha512-I0phtKJJdafUiDwm7BBlEUOtogmu8+taxq6PtIrxZbllV9hWg59qkpuIsiFp+no7nfRVuaasNYHwNUhDAVQBig== dependencies: cmd-shim "^4.1.0" @@ -1257,7 +901,7 @@ "@lerna/create@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-4.0.0.tgz#b6947e9b5dfb6530321952998948c3e63d64d730" + resolved "https://registry.npmjs.org/@lerna/create/-/create-4.0.0.tgz" integrity sha512-mVOB1niKByEUfxlbKTM1UNECWAjwUdiioIbRQZEeEabtjCL69r9rscIsjlGyhGWCfsdAG5wfq4t47nlDXdLLag== dependencies: "@lerna/child-process" "4.0.0" @@ -1281,7 +925,7 @@ "@lerna/describe-ref@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-4.0.0.tgz#53c53b4ea65fdceffa072a62bfebe6772c45d9ec" + resolved "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-4.0.0.tgz" integrity sha512-eTU5+xC4C5Gcgz+Ey4Qiw9nV2B4JJbMulsYJMW8QjGcGh8zudib7Sduj6urgZXUYNyhYpRs+teci9M2J8u+UvQ== dependencies: "@lerna/child-process" "4.0.0" @@ -1289,7 +933,7 @@ "@lerna/diff@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-4.0.0.tgz#6d3071817aaa4205a07bf77cfc6e932796d48b92" + resolved "https://registry.npmjs.org/@lerna/diff/-/diff-4.0.0.tgz" integrity sha512-jYPKprQVg41+MUMxx6cwtqsNm0Yxx9GDEwdiPLwcUTFx+/qKCEwifKNJ1oGIPBxyEHX2PFCOjkK39lHoj2qiag== dependencies: "@lerna/child-process" "4.0.0" @@ -1299,7 +943,7 @@ "@lerna/exec@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-4.0.0.tgz#eb6cb95cb92d42590e9e2d628fcaf4719d4a8be6" + resolved "https://registry.npmjs.org/@lerna/exec/-/exec-4.0.0.tgz" integrity sha512-VGXtL/b/JfY84NB98VWZpIExfhLOzy0ozm/0XaS4a2SmkAJc5CeUfrhvHxxkxiTBLkU+iVQUyYEoAT0ulQ8PCw== dependencies: "@lerna/child-process" "4.0.0" @@ -1312,7 +956,7 @@ "@lerna/filter-options@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-4.0.0.tgz#ac94cc515d7fa3b47e2f7d74deddeabb1de5e9e6" + resolved "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-4.0.0.tgz" integrity sha512-vV2ANOeZhOqM0rzXnYcFFCJ/kBWy/3OA58irXih9AMTAlQLymWAK0akWybl++sUJ4HB9Hx12TOqaXbYS2NM5uw== dependencies: "@lerna/collect-updates" "4.0.0" @@ -1322,7 +966,7 @@ "@lerna/filter-packages@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-4.0.0.tgz#b1f70d70e1de9cdd36a4e50caa0ac501f8d012f2" + resolved "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-4.0.0.tgz" integrity sha512-+4AJIkK7iIiOaqCiVTYJxh/I9qikk4XjNQLhE3kixaqgMuHl1NQ99qXRR0OZqAWB9mh8Z1HA9bM5K1HZLBTOqA== dependencies: "@lerna/validation-error" "4.0.0" @@ -1331,14 +975,14 @@ "@lerna/get-npm-exec-opts@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-4.0.0.tgz#dc955be94a4ae75c374ef9bce91320887d34608f" + resolved "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-4.0.0.tgz" integrity sha512-yvmkerU31CTWS2c7DvmAWmZVeclPBqI7gPVr5VATUKNWJ/zmVcU4PqbYoLu92I9Qc4gY1TuUplMNdNuZTSL7IQ== dependencies: npmlog "^4.1.2" "@lerna/get-packed@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-4.0.0.tgz#0989d61624ac1f97e393bdad2137c49cd7a37823" + resolved "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-4.0.0.tgz" integrity sha512-rfWONRsEIGyPJTxFzC8ECb3ZbsDXJbfqWYyeeQQDrJRPnEJErlltRLPLgC2QWbxFgFPsoDLeQmFHJnf0iDfd8w== dependencies: fs-extra "^9.1.0" @@ -1347,7 +991,7 @@ "@lerna/github-client@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-4.0.0.tgz#2ced67721363ef70f8e12ffafce4410918f4a8a4" + resolved "https://registry.npmjs.org/@lerna/github-client/-/github-client-4.0.0.tgz" integrity sha512-2jhsldZtTKXYUBnOm23Lb0Fx8G4qfSXF9y7UpyUgWUj+YZYd+cFxSuorwQIgk5P4XXrtVhsUesIsli+BYSThiw== dependencies: "@lerna/child-process" "4.0.0" @@ -1358,7 +1002,7 @@ "@lerna/gitlab-client@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-4.0.0.tgz#00dad73379c7b38951d4b4ded043504c14e2b67d" + resolved "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-4.0.0.tgz" integrity sha512-OMUpGSkeDWFf7BxGHlkbb35T7YHqVFCwBPSIR6wRsszY8PAzCYahtH3IaJzEJyUg6vmZsNl0FSr3pdA2skhxqA== dependencies: node-fetch "^2.6.1" @@ -1367,12 +1011,12 @@ "@lerna/global-options@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-4.0.0.tgz#c7d8b0de6a01d8a845e2621ea89e7f60f18c6a5f" + resolved "https://registry.npmjs.org/@lerna/global-options/-/global-options-4.0.0.tgz" integrity sha512-TRMR8afAHxuYBHK7F++Ogop2a82xQjoGna1dvPOY6ltj/pEx59pdgcJfYcynYqMkFIk8bhLJJN9/ndIfX29FTQ== "@lerna/has-npm-version@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-4.0.0.tgz#d3fc3292c545eb28bd493b36e6237cf0279f631c" + resolved "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-4.0.0.tgz" integrity sha512-LQ3U6XFH8ZmLCsvsgq1zNDqka0Xzjq5ibVN+igAI5ccRWNaUsE/OcmsyMr50xAtNQMYMzmpw5GVLAivT2/YzCg== dependencies: "@lerna/child-process" "4.0.0" @@ -1380,7 +1024,7 @@ "@lerna/import@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/import/-/import-4.0.0.tgz#bde656c4a451fa87ae41733ff8a8da60547c5465" + resolved "https://registry.npmjs.org/@lerna/import/-/import-4.0.0.tgz" integrity sha512-FaIhd+4aiBousKNqC7TX1Uhe97eNKf5/SC7c5WZANVWtC7aBWdmswwDt3usrzCNpj6/Wwr9EtEbYROzxKH8ffg== dependencies: "@lerna/child-process" "4.0.0" @@ -1394,7 +1038,7 @@ "@lerna/info@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/info/-/info-4.0.0.tgz#b9fb0e479d60efe1623603958a831a88b1d7f1fc" + resolved "https://registry.npmjs.org/@lerna/info/-/info-4.0.0.tgz" integrity sha512-8Uboa12kaCSZEn4XRfPz5KU9XXoexSPS4oeYGj76s2UQb1O1GdnEyfjyNWoUl1KlJ2i/8nxUskpXIftoFYH0/Q== dependencies: "@lerna/command" "4.0.0" @@ -1403,7 +1047,7 @@ "@lerna/init@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/init/-/init-4.0.0.tgz#dadff67e6dfb981e8ccbe0e6a310e837962f6c7a" + resolved "https://registry.npmjs.org/@lerna/init/-/init-4.0.0.tgz" integrity sha512-wY6kygop0BCXupzWj5eLvTUqdR7vIAm0OgyV9WHpMYQGfs1V22jhztt8mtjCloD/O0nEe4tJhdG62XU5aYmPNQ== dependencies: "@lerna/child-process" "4.0.0" @@ -1414,7 +1058,7 @@ "@lerna/link@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/link/-/link-4.0.0.tgz#c3a38aabd44279d714e90f2451e31b63f0fb65ba" + resolved "https://registry.npmjs.org/@lerna/link/-/link-4.0.0.tgz" integrity sha512-KlvPi7XTAcVOByfaLlOeYOfkkDcd+bejpHMCd1KcArcFTwijOwXOVi24DYomIeHvy6HsX/IUquJ4PPUJIeB4+w== dependencies: "@lerna/command" "4.0.0" @@ -1425,7 +1069,7 @@ "@lerna/list@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/list/-/list-4.0.0.tgz#24b4e6995bd73f81c556793fe502b847efd9d1d7" + resolved "https://registry.npmjs.org/@lerna/list/-/list-4.0.0.tgz" integrity sha512-L2B5m3P+U4Bif5PultR4TI+KtW+SArwq1i75QZ78mRYxPc0U/piau1DbLOmwrdqr99wzM49t0Dlvl6twd7GHFg== dependencies: "@lerna/command" "4.0.0" @@ -1435,7 +1079,7 @@ "@lerna/listable@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-4.0.0.tgz#d00d6cb4809b403f2b0374fc521a78e318b01214" + resolved "https://registry.npmjs.org/@lerna/listable/-/listable-4.0.0.tgz" integrity sha512-/rPOSDKsOHs5/PBLINZOkRIX1joOXUXEtyUs5DHLM8q6/RP668x/1lFhw6Dx7/U+L0+tbkpGtZ1Yt0LewCLgeQ== dependencies: "@lerna/query-graph" "4.0.0" @@ -1444,7 +1088,7 @@ "@lerna/log-packed@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-4.0.0.tgz#95168fe2e26ac6a71e42f4be857519b77e57a09f" + resolved "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-4.0.0.tgz" integrity sha512-+dpCiWbdzgMAtpajLToy9PO713IHoE6GV/aizXycAyA07QlqnkpaBNZ8DW84gHdM1j79TWockGJo9PybVhrrZQ== dependencies: byte-size "^7.0.0" @@ -1454,7 +1098,7 @@ "@lerna/npm-conf@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-4.0.0.tgz#b259fd1e1cee2bf5402b236e770140ff9ade7fd2" + resolved "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-4.0.0.tgz" integrity sha512-uS7H02yQNq3oejgjxAxqq/jhwGEE0W0ntr8vM3EfpCW1F/wZruwQw+7bleJQ9vUBjmdXST//tk8mXzr5+JXCfw== dependencies: config-chain "^1.1.12" @@ -1462,7 +1106,7 @@ "@lerna/npm-dist-tag@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-4.0.0.tgz#d1e99b4eccd3414142f0548ad331bf2d53f3257a" + resolved "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-4.0.0.tgz" integrity sha512-F20sg28FMYTgXqEQihgoqSfwmq+Id3zT23CnOwD+XQMPSy9IzyLf1fFVH319vXIw6NF6Pgs4JZN2Qty6/CQXGw== dependencies: "@lerna/otplease" "4.0.0" @@ -1472,7 +1116,7 @@ "@lerna/npm-install@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-4.0.0.tgz#31180be3ab3b7d1818a1a0c206aec156b7094c78" + resolved "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-4.0.0.tgz" integrity sha512-aKNxq2j3bCH3eXl3Fmu4D54s/YLL9WSwV8W7X2O25r98wzrO38AUN6AB9EtmAx+LV/SP15et7Yueg9vSaanRWg== dependencies: "@lerna/child-process" "4.0.0" @@ -1485,7 +1129,7 @@ "@lerna/npm-publish@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-4.0.0.tgz#84eb62e876fe949ae1fd62c60804423dbc2c4472" + resolved "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-4.0.0.tgz" integrity sha512-vQb7yAPRo5G5r77DRjHITc9piR9gvEKWrmfCH7wkfBnGWEqu7n8/4bFQ7lhnkujvc8RXOsYpvbMQkNfkYibD/w== dependencies: "@lerna/otplease" "4.0.0" @@ -1499,7 +1143,7 @@ "@lerna/npm-run-script@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-4.0.0.tgz#dfebf4f4601442e7c0b5214f9fb0d96c9350743b" + resolved "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-4.0.0.tgz" integrity sha512-Jmyh9/IwXJjOXqKfIgtxi0bxi1pUeKe5bD3S81tkcy+kyng/GNj9WSqD5ZggoNP2NP//s4CLDAtUYLdP7CU9rA== dependencies: "@lerna/child-process" "4.0.0" @@ -1508,21 +1152,21 @@ "@lerna/otplease@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-4.0.0.tgz#84972eb43448f8a1077435ba1c5e59233b725850" + resolved "https://registry.npmjs.org/@lerna/otplease/-/otplease-4.0.0.tgz" integrity sha512-Sgzbqdk1GH4psNiT6hk+BhjOfIr/5KhGBk86CEfHNJTk9BK4aZYyJD4lpDbDdMjIV4g03G7pYoqHzH765T4fxw== dependencies: "@lerna/prompt" "4.0.0" "@lerna/output@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/output/-/output-4.0.0.tgz#b1d72215c0e35483e4f3e9994debc82c621851f2" + resolved "https://registry.npmjs.org/@lerna/output/-/output-4.0.0.tgz" integrity sha512-Un1sHtO1AD7buDQrpnaYTi2EG6sLF+KOPEAMxeUYG5qG3khTs2Zgzq5WE3dt2N/bKh7naESt20JjIW6tBELP0w== dependencies: npmlog "^4.1.2" "@lerna/pack-directory@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-4.0.0.tgz#8b617db95d20792f043aaaa13a9ccc0e04cb4c74" + resolved "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-4.0.0.tgz" integrity sha512-NJrmZNmBHS+5aM+T8N6FVbaKFScVqKlQFJNY2k7nsJ/uklNKsLLl6VhTQBPwMTbf6Tf7l6bcKzpy7aePuq9UiQ== dependencies: "@lerna/get-packed" "4.0.0" @@ -1535,7 +1179,7 @@ "@lerna/package-graph@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-4.0.0.tgz#16a00253a8ac810f72041481cb46bcee8d8123dd" + resolved "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-4.0.0.tgz" integrity sha512-QED2ZCTkfXMKFoTGoccwUzjHtZMSf3UKX14A4/kYyBms9xfFsesCZ6SLI5YeySEgcul8iuIWfQFZqRw+Qrjraw== dependencies: "@lerna/prerelease-id-from-version" "4.0.0" @@ -1546,7 +1190,7 @@ "@lerna/package@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/package/-/package-4.0.0.tgz#1b4c259c4bcff45c876ee1d591a043aacbc0d6b7" + resolved "https://registry.npmjs.org/@lerna/package/-/package-4.0.0.tgz" integrity sha512-l0M/izok6FlyyitxiQKr+gZLVFnvxRQdNhzmQ6nRnN9dvBJWn+IxxpM+cLqGACatTnyo9LDzNTOj2Db3+s0s8Q== dependencies: load-json-file "^6.2.0" @@ -1555,14 +1199,14 @@ "@lerna/prerelease-id-from-version@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-4.0.0.tgz#c7e0676fcee1950d85630e108eddecdd5b48c916" + resolved "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-4.0.0.tgz" integrity sha512-GQqguzETdsYRxOSmdFZ6zDBXDErIETWOqomLERRY54f4p+tk4aJjoVdd9xKwehC9TBfIFvlRbL1V9uQGHh1opg== dependencies: semver "^7.3.4" "@lerna/profiler@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-4.0.0.tgz#8a53ab874522eae15d178402bff90a14071908e9" + resolved "https://registry.npmjs.org/@lerna/profiler/-/profiler-4.0.0.tgz" integrity sha512-/BaEbqnVh1LgW/+qz8wCuI+obzi5/vRE8nlhjPzdEzdmWmZXuCKyWSEzAyHOJWw1ntwMiww5dZHhFQABuoFz9Q== dependencies: fs-extra "^9.1.0" @@ -1571,7 +1215,7 @@ "@lerna/project@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/project/-/project-4.0.0.tgz#ff84893935833533a74deff30c0e64ddb7f0ba6b" + resolved "https://registry.npmjs.org/@lerna/project/-/project-4.0.0.tgz" integrity sha512-o0MlVbDkD5qRPkFKlBZsXZjoNTWPyuL58564nSfZJ6JYNmgAptnWPB2dQlAc7HWRZkmnC2fCkEdoU+jioPavbg== dependencies: "@lerna/package" "4.0.0" @@ -1589,7 +1233,7 @@ "@lerna/prompt@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-4.0.0.tgz#5ec69a803f3f0db0ad9f221dad64664d3daca41b" + resolved "https://registry.npmjs.org/@lerna/prompt/-/prompt-4.0.0.tgz" integrity sha512-4Ig46oCH1TH5M7YyTt53fT6TuaKMgqUUaqdgxvp6HP6jtdak6+amcsqB8YGz2eQnw/sdxunx84DfI9XpoLj4bQ== dependencies: inquirer "^7.3.3" @@ -1597,7 +1241,7 @@ "@lerna/publish@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-4.0.0.tgz#f67011305adeba120066a3b6d984a5bb5fceef65" + resolved "https://registry.npmjs.org/@lerna/publish/-/publish-4.0.0.tgz" integrity sha512-K8jpqjHrChH22qtkytA5GRKIVFEtqBF6JWj1I8dWZtHs4Jywn8yB1jQ3BAMLhqmDJjWJtRck0KXhQQKzDK2UPg== dependencies: "@lerna/check-working-tree" "4.0.0" @@ -1631,21 +1275,21 @@ "@lerna/pulse-till-done@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-4.0.0.tgz#04bace7d483a8205c187b806bcd8be23d7bb80a3" + resolved "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-4.0.0.tgz" integrity sha512-Frb4F7QGckaybRhbF7aosLsJ5e9WuH7h0KUkjlzSByVycxY91UZgaEIVjS2oN9wQLrheLMHl6SiFY0/Pvo0Cxg== dependencies: npmlog "^4.1.2" "@lerna/query-graph@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-4.0.0.tgz#09dd1c819ac5ee3f38db23931143701f8a6eef63" + resolved "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-4.0.0.tgz" integrity sha512-YlP6yI3tM4WbBmL9GCmNDoeQyzcyg1e4W96y/PKMZa5GbyUvkS2+Jc2kwPD+5KcXou3wQZxSPzR3Te5OenaDdg== dependencies: "@lerna/package-graph" "4.0.0" "@lerna/resolve-symlink@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-4.0.0.tgz#6d006628a210c9b821964657a9e20a8c9a115e14" + resolved "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-4.0.0.tgz" integrity sha512-RtX8VEUzqT+uLSCohx8zgmjc6zjyRlh6i/helxtZTMmc4+6O4FS9q5LJas2uGO2wKvBlhcD6siibGt7dIC3xZA== dependencies: fs-extra "^9.1.0" @@ -1654,7 +1298,7 @@ "@lerna/rimraf-dir@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-4.0.0.tgz#2edf3b62d4eb0ef4e44e430f5844667d551ec25a" + resolved "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-4.0.0.tgz" integrity sha512-QNH9ABWk9mcMJh2/muD9iYWBk1oQd40y6oH+f3wwmVGKYU5YJD//+zMiBI13jxZRtwBx0vmBZzkBkK1dR11cBg== dependencies: "@lerna/child-process" "4.0.0" @@ -1664,7 +1308,7 @@ "@lerna/run-lifecycle@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-4.0.0.tgz#e648a46f9210a9bcd7c391df6844498cb5079334" + resolved "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-4.0.0.tgz" integrity sha512-IwxxsajjCQQEJAeAaxF8QdEixfI7eLKNm4GHhXHrgBu185JcwScFZrj9Bs+PFKxwb+gNLR4iI5rpUdY8Y0UdGQ== dependencies: "@lerna/npm-conf" "4.0.0" @@ -1673,7 +1317,7 @@ "@lerna/run-topologically@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-4.0.0.tgz#af846eeee1a09b0c2be0d1bfb5ef0f7b04bb1827" + resolved "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-4.0.0.tgz" integrity sha512-EVZw9hGwo+5yp+VL94+NXRYisqgAlj0jWKWtAIynDCpghRxCE5GMO3xrQLmQgqkpUl9ZxQFpICgYv5DW4DksQA== dependencies: "@lerna/query-graph" "4.0.0" @@ -1681,7 +1325,7 @@ "@lerna/run@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/run/-/run-4.0.0.tgz#4bc7fda055a729487897c23579694f6183c91262" + resolved "https://registry.npmjs.org/@lerna/run/-/run-4.0.0.tgz" integrity sha512-9giulCOzlMPzcZS/6Eov6pxE9gNTyaXk0Man+iCIdGJNMrCnW7Dme0Z229WWP/UoxDKg71F2tMsVVGDiRd8fFQ== dependencies: "@lerna/command" "4.0.0" @@ -1696,7 +1340,7 @@ "@lerna/symlink-binary@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-4.0.0.tgz#21009f62d53a425f136cb4c1a32c6b2a0cc02d47" + resolved "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-4.0.0.tgz" integrity sha512-zualodWC4q1QQc1pkz969hcFeWXOsVYZC5AWVtAPTDfLl+TwM7eG/O6oP+Rr3fFowspxo6b1TQ6sYfDV6HXNWA== dependencies: "@lerna/create-symlink" "4.0.0" @@ -1706,7 +1350,7 @@ "@lerna/symlink-dependencies@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-4.0.0.tgz#8910eca084ae062642d0490d8972cf2d98e9ebbd" + resolved "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-4.0.0.tgz" integrity sha512-BABo0MjeUHNAe2FNGty1eantWp8u83BHSeIMPDxNq0MuW2K3CiQRaeWT3EGPAzXpGt0+hVzBrA6+OT0GPn7Yuw== dependencies: "@lerna/create-symlink" "4.0.0" @@ -1718,19 +1362,19 @@ "@lerna/timer@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-4.0.0.tgz#a52e51bfcd39bfd768988049ace7b15c1fd7a6da" + resolved "https://registry.npmjs.org/@lerna/timer/-/timer-4.0.0.tgz" integrity sha512-WFsnlaE7SdOvjuyd05oKt8Leg3ENHICnvX3uYKKdByA+S3g+TCz38JsNs7OUZVt+ba63nC2nbXDlUnuT2Xbsfg== "@lerna/validation-error@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-4.0.0.tgz#af9d62fe8304eaa2eb9a6ba1394f9aa807026d35" + resolved "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-4.0.0.tgz" integrity sha512-1rBOM5/koiVWlRi3V6dB863E1YzJS8v41UtsHgMr6gB2ncJ2LsQtMKlJpi3voqcgh41H8UsPXR58RrrpPpufyw== dependencies: npmlog "^4.1.2" "@lerna/version@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-4.0.0.tgz#532659ec6154d8a8789c5ab53878663e244e3228" + resolved "https://registry.npmjs.org/@lerna/version/-/version-4.0.0.tgz" integrity sha512-otUgiqs5W9zGWJZSCCMRV/2Zm2A9q9JwSDS7s/tlKq4mWCYriWo7+wsHEA/nPTMDyYyBO5oyZDj+3X50KDUzeA== dependencies: "@lerna/check-working-tree" "4.0.0" @@ -1762,7 +1406,7 @@ "@lerna/write-log-file@4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-4.0.0.tgz#18221a38a6a307d6b0a5844dd592ad53fa27091e" + resolved "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-4.0.0.tgz" integrity sha512-XRG5BloiArpXRakcnPHmEHJp+4AtnhRtpDIHSghmXD5EichI1uD73J7FgPp30mm2pDRq3FdqB0NbwSEsJ9xFQg== dependencies: npmlog "^4.1.2" @@ -1770,7 +1414,7 @@ "@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" + resolved "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz" integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== dependencies: ethereumjs-abi "^0.6.8" @@ -1781,17 +1425,17 @@ "@noble/hashes@1.0.0", "@noble/hashes@~1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz" integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== "@noble/secp256k1@1.5.5", "@noble/secp256k1@~1.5.2": version "1.5.5" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.5.5.tgz#315ab5745509d1a8c8e90d0bdf59823ccf9bcfc3" + resolved "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.5.5.tgz" integrity sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ== "@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" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -1799,12 +1443,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -1812,7 +1456,7 @@ "@nomicfoundation/ethereumjs-block@^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz#fdd5c045e7baa5169abeed0e1202bf94e4481c49" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz" integrity sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA== dependencies: "@nomicfoundation/ethereumjs-common" "^3.0.0" @@ -1824,7 +1468,7 @@ "@nomicfoundation/ethereumjs-blockchain@^6.0.0": version "6.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz#1a8c243a46d4d3691631f139bfb3a4a157187b0c" + 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" @@ -1842,7 +1486,7 @@ "@nomicfoundation/ethereumjs-common@^3.0.0": version "3.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz#f6bcc7753994555e49ab3aa517fc8bcf89c280b9" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz" integrity sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA== dependencies: "@nomicfoundation/ethereumjs-util" "^8.0.0" @@ -1850,7 +1494,7 @@ "@nomicfoundation/ethereumjs-ethash@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz#11539c32fe0990e1122ff987d1b84cfa34774e81" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz" integrity sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew== dependencies: "@nomicfoundation/ethereumjs-block" "^4.0.0" @@ -1862,7 +1506,7 @@ "@nomicfoundation/ethereumjs-evm@^1.0.0", "@nomicfoundation/ethereumjs-evm@^1.0.0-rc.3": version "1.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz#99cd173c03b59107c156a69c5e215409098a370b" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz" integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q== dependencies: "@nomicfoundation/ethereumjs-common" "^3.0.0" @@ -1876,12 +1520,12 @@ "@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2": version "4.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz#d9a9c5f0f10310c8849b6525101de455a53e771d" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz" integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw== "@nomicfoundation/ethereumjs-statemanager@^1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz#14a9d4e1c828230368f7ab520c144c34d8721e4b" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz" integrity sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ== dependencies: "@nomicfoundation/ethereumjs-common" "^3.0.0" @@ -1894,7 +1538,7 @@ "@nomicfoundation/ethereumjs-trie@^5.0.0": version "5.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz#dcfbe3be53a94bc061c9767a396c16702bc2f5b7" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz" integrity sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A== dependencies: "@nomicfoundation/ethereumjs-rlp" "^4.0.0" @@ -1904,7 +1548,7 @@ "@nomicfoundation/ethereumjs-tx@^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz#59dc7452b0862b30342966f7052ab9a1f7802f52" + 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" @@ -1914,7 +1558,7 @@ "@nomicfoundation/ethereumjs-util@^8.0.0", "@nomicfoundation/ethereumjs-util@^8.0.0-rc.3": version "8.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz#deb2b15d2c308a731e82977aefc4e61ca0ece6c5" + resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz" integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A== dependencies: "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2" @@ -1922,7 +1566,7 @@ "@nomicfoundation/ethereumjs-vm@^6.0.0", "@nomicfoundation/ethereumjs-vm@^6.0.0-rc.3": version "6.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz#2bb50d332bf41790b01a3767ffec3987585d1de6" + 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" @@ -1944,7 +1588,7 @@ "@nomicfoundation/hardhat-chai-matchers@^1.0.4": version "1.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.4.tgz#4b5c0d6eba637aabb49342272ae15ee6877a462e" + resolved "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.4.tgz" integrity sha512-n/5UMwGaUK2zM8ALuMChVwB1lEPeDTb5oBjQ1g7hVsUdS8x+XG9JIEp4Ze6Bwy98tghA7Y1+PCH4SNE2P3UQ2g== dependencies: "@ethersproject/abi" "^5.1.2" @@ -1963,7 +1607,7 @@ "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760" + resolved "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz" integrity sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw== "@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0": @@ -2013,7 +1657,7 @@ "@nomicfoundation/solidity-analyzer@^0.1.0": version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz#e5ddc43ad5c0aab96e5054520d8e16212e125f50" + resolved "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz" integrity sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg== optionalDependencies: "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.0" @@ -2029,7 +1673,7 @@ "@nomiclabs/hardhat-ethers@^2.2.1": version "2.2.1" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz#8057b43566a0e41abeb8142064a3c0d3f23dca86" + resolved "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz" integrity sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg== "@nomiclabs/hardhat-etherscan@^3.1.1": @@ -2050,12 +1694,12 @@ "@npmcli/ci-detect@^1.0.0": version "1.4.0" - resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1" + resolved "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz" integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q== "@npmcli/fs@^1.0.0": version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz" integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== dependencies: "@gar/promisify" "^1.0.1" @@ -2063,7 +1707,7 @@ "@npmcli/git@^2.1.0": version "2.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6" + resolved "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz" integrity sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw== dependencies: "@npmcli/promise-spawn" "^1.3.2" @@ -2077,7 +1721,7 @@ "@npmcli/installed-package-contents@^1.0.6": version "1.0.7" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" + resolved "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz" integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== dependencies: npm-bundled "^1.1.1" @@ -2085,7 +1729,7 @@ "@npmcli/move-file@^1.0.1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz" integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== dependencies: mkdirp "^1.0.4" @@ -2093,19 +1737,19 @@ "@npmcli/node-gyp@^1.0.2": version "1.0.3" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" + resolved "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz" integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== "@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": version "1.3.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" + resolved "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz" integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== dependencies: infer-owner "^1.0.4" "@npmcli/run-script@^1.8.2": version "1.8.6" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.6.tgz#18314802a6660b0d4baa4c3afe7f1ad39d8c28b7" + resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.6.tgz" integrity sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g== dependencies: "@npmcli/node-gyp" "^1.0.2" @@ -2115,14 +1759,14 @@ "@octokit/auth-token@^2.4.4": version "2.5.0" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36" + resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz" integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g== dependencies: "@octokit/types" "^6.0.3" "@octokit/core@^3.5.1": version "3.6.0" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.6.0.tgz#3376cb9f3008d9b3d110370d90e0a1fcd5fe6085" + resolved "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz" integrity sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q== dependencies: "@octokit/auth-token" "^2.4.4" @@ -2135,7 +1779,7 @@ "@octokit/endpoint@^6.0.1": version "6.0.12" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.12.tgz#3b4d47a4b0e79b1027fb8d75d4221928b2d05658" + resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz" integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA== dependencies: "@octokit/types" "^6.0.3" @@ -2144,7 +1788,7 @@ "@octokit/graphql@^4.5.8": version "4.8.0" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" + resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz" integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg== dependencies: "@octokit/request" "^5.6.0" @@ -2153,29 +1797,29 @@ "@octokit/openapi-types@^11.2.0": version "11.2.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-11.2.0.tgz#b38d7fc3736d52a1e96b230c1ccd4a58a2f400a6" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz" integrity sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA== "@octokit/plugin-enterprise-rest@^6.0.1": version "6.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" + resolved "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz" integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== "@octokit/plugin-paginate-rest@^2.16.8": version "2.17.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz#32e9c7cab2a374421d3d0de239102287d791bce7" + resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz" integrity sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw== dependencies: "@octokit/types" "^6.34.0" "@octokit/plugin-request-log@^1.0.4": version "1.0.4" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" + resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz" integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== "@octokit/plugin-rest-endpoint-methods@^5.12.0": version "5.13.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz#8c46109021a3412233f6f50d28786f8e552427ba" + resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz" integrity sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA== dependencies: "@octokit/types" "^6.34.0" @@ -2183,7 +1827,7 @@ "@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": version "2.1.0" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677" + resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz" integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg== dependencies: "@octokit/types" "^6.0.3" @@ -2192,7 +1836,7 @@ "@octokit/request@^5.6.0", "@octokit/request@^5.6.3": version "5.6.3" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.3.tgz#19a022515a5bba965ac06c9d1334514eb50c48b0" + resolved "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz" integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A== dependencies: "@octokit/endpoint" "^6.0.1" @@ -2204,7 +1848,7 @@ "@octokit/rest@^18.1.0": version "18.12.0" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.12.0.tgz#f06bc4952fc87130308d810ca9d00e79f6988881" + resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz" integrity sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q== dependencies: "@octokit/core" "^3.5.1" @@ -2214,7 +1858,7 @@ "@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.34.0": version "6.34.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.34.0.tgz#c6021333334d1ecfb5d370a8798162ddf1ae8218" + resolved "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz" integrity sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw== dependencies: "@octokit/openapi-types" "^11.2.0" @@ -2226,12 +1870,12 @@ "@openzeppelin/contracts-v0.7@npm:@openzeppelin/contracts@v3.4.2": version "3.4.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527" + resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.2.tgz" integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA== "@openzeppelin/contracts@4.6.0": version "4.6.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.6.0.tgz#c91cf64bc27f573836dba4122758b4743418c1b3" + resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.6.0.tgz" integrity sha512-8vi4d50NNya/bQqCmaVzvHNmwHvS0OBKb7HNtuNwEE3scXWrP31fKQoGxNMT+KbzmrNZzatE3QK5p2gFONI/hg== "@openzeppelin/contracts@4.8.0": @@ -2246,7 +1890,7 @@ "@resolver-engine/core@^0.3.3": version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" + resolved "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz" integrity sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ== dependencies: debug "^3.1.0" @@ -2255,7 +1899,7 @@ "@resolver-engine/fs@^0.3.3": version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/fs/-/fs-0.3.3.tgz#fbf83fa0c4f60154a82c817d2fe3f3b0c049a973" + resolved "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz" integrity sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ== dependencies: "@resolver-engine/core" "^0.3.3" @@ -2263,7 +1907,7 @@ "@resolver-engine/imports-fs@^0.3.3": version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz#4085db4b8d3c03feb7a425fbfcf5325c0d1e6c1b" + resolved "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz" integrity sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA== dependencies: "@resolver-engine/fs" "^0.3.3" @@ -2272,7 +1916,7 @@ "@resolver-engine/imports@^0.3.3": version "0.3.3" - resolved "https://registry.yarnpkg.com/@resolver-engine/imports/-/imports-0.3.3.tgz#badfb513bb3ff3c1ee9fd56073e3144245588bcc" + resolved "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz" integrity sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q== dependencies: "@resolver-engine/core" "^0.3.3" @@ -2283,12 +1927,12 @@ "@scure/base@~1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7" + resolved "https://registry.npmjs.org/@scure/base/-/base-1.0.0.tgz" integrity sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA== "@scure/bip32@1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.0.1.tgz#1409bdf9f07f0aec99006bb0d5827693418d3aa5" + resolved "https://registry.npmjs.org/@scure/bip32/-/bip32-1.0.1.tgz" integrity sha512-AU88KKTpQ+YpTLoicZ/qhFhRRIo96/tlb+8YmDDHR9yiKVjSsFZiefJO4wjS2PMTkz5/oIcw84uAq/8pleQURA== dependencies: "@noble/hashes" "~1.0.0" @@ -2297,7 +1941,7 @@ "@scure/bip39@1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.0.0.tgz#47504e58de9a56a4bbed95159d2d6829fa491bb0" + resolved "https://registry.npmjs.org/@scure/bip39/-/bip39-1.0.0.tgz" integrity sha512-HrtcikLbd58PWOkl02k9V6nXWQyoa7A0+Ek9VF7z17DDk9XZAFUcIdqfh0jJXLypmizc5/8P6OxoUeKliiWv4w== dependencies: "@noble/hashes" "~1.0.0" @@ -2305,7 +1949,7 @@ "@sentry/core@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + resolved "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz" integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== dependencies: "@sentry/hub" "5.30.0" @@ -2316,7 +1960,7 @@ "@sentry/hub@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz" integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== dependencies: "@sentry/types" "5.30.0" @@ -2325,7 +1969,7 @@ "@sentry/minimal@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz" integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== dependencies: "@sentry/hub" "5.30.0" @@ -2334,7 +1978,7 @@ "@sentry/node@^5.18.1": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + resolved "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz" integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== dependencies: "@sentry/core" "5.30.0" @@ -2349,7 +1993,7 @@ "@sentry/tracing@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + resolved "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz" integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== dependencies: "@sentry/hub" "5.30.0" @@ -2360,12 +2004,12 @@ "@sentry/types@5.30.0": version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + resolved "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz" 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" + resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz" integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== dependencies: "@sentry/types" "5.30.0" @@ -2373,31 +2017,31 @@ "@sindresorhus/is@^0.14.0": version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@solidity-parser/parser@^0.14.0", "@solidity-parser/parser@^0.14.1": version "0.14.2" - resolved "https://registry.yarnpkg.com/@equilibria/parser/-/parser-0.14.2.tgz#f29ff8f297cf36e1ef8b9005c7fc61c398b7cbf5" + resolved "https://registry.npmjs.org/@equilibria/parser/-/parser-0.14.2.tgz" integrity sha512-cVRgIYOhScWcQ0zg/lSeZFz06qthFAOdQwOin+tVK2ysh7uFAHCUmSZCVUPYW7nVg87dOENnYitL77lA0aMp1Q== dependencies: antlr4ts "^0.5.0-alpha.4" "@szmarczak/http-timer@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== dependencies: defer-to-connect "^1.0.1" "@tootallnate/once@1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@typechain/ethers-v5@^10.1.0": version "10.1.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.1.0.tgz#068d7dc7014502354696dab59590a7841091e951" + resolved "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.1.0.tgz" integrity sha512-3LIb+eUpV3mNCrjUKT5oqp8PBsZYSnVrkfk6pY/ZM0boRs2mKxjFZ7bktx42vfDye8PPz3NxtW4DL5NsNsFqlg== dependencies: lodash "^4.17.15" @@ -2405,14 +2049,14 @@ "@typechain/ethers-v5@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz#cd3ca1590240d587ca301f4c029b67bfccd08810" + resolved "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz" integrity sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw== dependencies: ethers "^5.0.2" "@typechain/hardhat@^6.1.0": version "6.1.2" - resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.2.tgz#d3beccc6937d93f9b437616b741f839a8b953693" + resolved "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-6.1.2.tgz" integrity sha512-k4Ea3pVITKB2DH8p1a5U38cyy7KZPD04Spo4q5b4wO+n2mT+uAz5dxckPtbczn/Kk5wiFq+ZkuOtw5ZKFhL/+w== dependencies: fs-extra "^9.1.0" @@ -2420,52 +2064,52 @@ "@types/async-eventemitter@^0.2.1": version "0.2.1" - resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" + resolved "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz" integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg== "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz" integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== dependencies: "@types/node" "*" "@types/bn.js@^5.1.0": version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz" integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== dependencies: "@types/node" "*" "@types/chai-as-promised@^7.1.3": version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" + resolved "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz" integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== dependencies: "@types/chai" "*" "@types/chai@*", "@types/chai@^4.2.14": version "4.3.1" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz" integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ== "@types/concat-stream@^1.6.0": version "1.6.1" - resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-1.6.1.tgz#24bcfc101ecf68e886aaedce60dfd74b632a1b74" + resolved "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz" integrity sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA== dependencies: "@types/node" "*" "@types/form-data@0.0.33": version "0.0.33" - resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" - integrity sha1-yayFsqX9GENbjIXZ7LUObWyJP/g= + resolved "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz" + integrity "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g= sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==" 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" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" @@ -2473,113 +2117,108 @@ "@types/json-schema@^7.0.7": version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@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" + resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz" integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== "@types/minimatch@*", "@types/minimatch@^3.0.3": version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/mkdirp@^0.5.2": version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + resolved "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz" integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== dependencies: "@types/node" "*" "@types/mocha@^8.0.4": version "8.2.3" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz" integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== "@types/node-fetch@^2.5.5": version "2.6.1" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" + resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz" integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA== dependencies: "@types/node" "*" form-data "^3.0.0" -"@types/node@*": - version "17.0.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.33.tgz#3c1879b276dc63e73030bb91165e62a4509cd506" - integrity sha512-miWq2m2FiQZmaHfdZNcbpp9PuXg34W5JZ5CrJ/BaS70VuhoJENBEQybeiYSaPBRNq6KQGnjfEnc/F3PN++D+XQ== +"@types/node@*", "@types/node@^14.14.10": + version "14.18.18" + resolved "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz" + integrity sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig== "@types/node@^10.0.3": version "10.17.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + resolved "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^12.12.6": - version "12.20.52" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.52.tgz#2fd2dc6bfa185601b15457398d4ba1ef27f81251" - integrity sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw== - -"@types/node@^14.14.10": - version "14.18.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.18.tgz#5c9503030df484ccffcbb935ea9a9e1d6fad1a20" - integrity sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig== + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/node@^8.0.0": version "8.10.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" + resolved "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz" integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== "@types/normalize-package-data@^2.4.0": version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== "@types/parse-json@^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/pbkdf2@^3.0.0": version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" + resolved "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz" integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== dependencies: "@types/node" "*" "@types/prettier@^2.1.1": version "2.6.4" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.4.tgz#ad899dad022bab6b5a9f0a0fe67c2f7a4a8950ed" + resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz" integrity sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw== "@types/qs@^6.2.31", "@types/qs@^6.9.7": version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== "@types/resolve@^0.0.8": version "0.0.8" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" + resolved "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz" integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== dependencies: "@types/node" "*" "@types/secp256k1@^4.0.1": version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" + resolved "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz" integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== dependencies: "@types/node" "*" "@typescript-eslint/eslint-plugin@^4.26.1": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz" integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== dependencies: "@typescript-eslint/experimental-utils" "4.33.0" @@ -2593,7 +2232,7 @@ "@typescript-eslint/experimental-utils@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz" integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== dependencies: "@types/json-schema" "^7.0.7" @@ -2605,7 +2244,7 @@ "@typescript-eslint/parser@^4.26.1": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz" integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== dependencies: "@typescript-eslint/scope-manager" "4.33.0" @@ -2615,7 +2254,7 @@ "@typescript-eslint/scope-manager@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz" integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== dependencies: "@typescript-eslint/types" "4.33.0" @@ -2623,12 +2262,12 @@ "@typescript-eslint/types@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz" integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== "@typescript-eslint/typescript-estree@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz" integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== dependencies: "@typescript-eslint/types" "4.33.0" @@ -2641,7 +2280,7 @@ "@typescript-eslint/visitor-keys@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz" integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== dependencies: "@typescript-eslint/types" "4.33.0" @@ -2649,17 +2288,17 @@ "@ungap/promise-all-settled@1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== "@yarnpkg/lockfile@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== JSONStream@^1.0.4: version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== dependencies: jsonparse "^1.2.0" @@ -2667,24 +2306,24 @@ JSONStream@^1.0.4: abbrev@1: version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== abbrev@1.0.x: version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" + integrity "sha1-kbR5JYinc4wl813W9jdSovh3YTU= sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==" abort-controller@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + 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" 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" + resolved "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz" integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== dependencies: buffer "^6.0.3" @@ -2697,28 +2336,28 @@ abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: abstract-leveldown@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" + resolved "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz" integrity sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ== dependencies: xtend "~4.0.0" abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: version "2.7.2" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" + resolved "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz" integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== dependencies: xtend "~4.0.0" abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" + resolved "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz" integrity sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A== dependencies: xtend "~4.0.0" abstract-leveldown@~2.6.0: version "2.6.3" - resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" + resolved "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz" integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== dependencies: xtend "~4.0.0" @@ -2733,54 +2372,54 @@ accepts@~1.3.8: acorn-jsx@^5.0.0, acorn-jsx@^5.3.1: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn@^6.0.7: version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== acorn@^7.4.0: version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== add-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= + resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz" + integrity "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==" address@^1.0.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9" + resolved "https://registry.npmjs.org/address/-/address-1.2.0.tgz" integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig== adm-zip@^0.4.16: version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz" 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 sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= + resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz" + integrity "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" aes-js@^3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz" integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== agent-base@6, agent-base@^6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" agentkeepalive@^4.1.3: version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz" integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== dependencies: debug "^4.1.0" @@ -2789,7 +2428,7 @@ agentkeepalive@^4.1.3: aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -2797,7 +2436,7 @@ aggregate-error@^3.0.0: ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.6.1, ajv@^6.9.1: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -2807,7 +2446,7 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.6.1, ajv@^6.9.1: ajv@^8.0.1: version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz" integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== dependencies: fast-deep-equal "^3.1.1" @@ -2817,98 +2456,98 @@ ajv@^8.0.1: amdefine@>=0.0.4: version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz" + integrity "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==" ansi-colors@3.2.3: version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz" integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== ansi-colors@4.1.1, ansi-colors@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-escapes@^3.1.0, ansi-escapes@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + integrity "sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" ansi-regex@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== ansi-regex@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== ansi-styles@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" ansi-styles@^6.0.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz" integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== ansicolors@~0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= + resolved "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz" + integrity "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==" antlr4@4.7.1: version "4.7.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" + resolved "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz" integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== antlr4ts@^0.5.0-alpha.4: version "0.5.0-alpha.4" - resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + resolved "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz" integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" @@ -2916,17 +2555,17 @@ anymatch@~3.1.1, anymatch@~3.1.2: aproba@^1.0.3: version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== aproba@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== are-we-there-yet@~1.1.2: version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz" integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== dependencies: delegates "^1.0.0" @@ -2934,108 +2573,119 @@ are-we-there-yet@~1.1.2: arg@^4.1.0: version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== arr-diff@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-back@^1.0.3, array-back@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" + resolved "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz" integrity sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw== dependencies: typical "^2.6.0" array-back@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" + resolved "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz" integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== dependencies: typical "^2.6.1" array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + resolved "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz" integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== array-back@^4.0.1, array-back@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + resolved "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz" integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== array-differ@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" + resolved "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz" integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== array-flatten@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-ify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + resolved "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz" + integrity "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==" array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array-uniq@1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + integrity "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==" array-unique@^0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +array.prototype.reduce@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" + integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + arrify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + integrity "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" arrify@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + resolved "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== asap@^2.0.0, asap@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + integrity "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" asn1.js@^5.2.0: version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz" integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" @@ -3045,107 +2695,112 @@ asn1.js@^5.2.0: asn1@~0.2.3: version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== dependencies: safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + integrity "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" assertion-error@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= ast-parents@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" - integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= + resolved "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz" + integrity "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==" astral-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: version "0.2.4" - resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + 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.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== async@1.x, async@^1.4.2: version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + resolved "https://registry.npmjs.org/async/-/async-1.5.2.tgz" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= -async@2.6.2: +async@2.6.2, async@^2.0.1, async@^2.1.2, async@^2.5.0, async@^2.6.1: version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + resolved "https://registry.npmjs.org/async/-/async-2.6.2.tgz" integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== dependencies: lodash "^4.17.11" -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1: +async@^2.4.0: version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" at-least-node@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== atob@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + aws-sign2@~0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" + integrity "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" aws4@^1.8.0: version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== axios@^0.21.1: version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== dependencies: follow-redirects "^1.14.0" babel-code-frame@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= dependencies: chalk "^1.1.3" @@ -3154,7 +2809,7 @@ babel-code-frame@^6.26.0: babel-core@^6.0.14, babel-core@^6.26.0: version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + resolved "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz" integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== dependencies: babel-code-frame "^6.26.0" @@ -3179,7 +2834,7 @@ babel-core@^6.0.14, babel-core@^6.26.0: babel-generator@^6.26.0: version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + resolved "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz" integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== dependencies: babel-messages "^6.23.0" @@ -3193,7 +2848,7 @@ babel-generator@^6.26.0: babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + resolved "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz" integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= dependencies: babel-helper-explode-assignable-expression "^6.24.1" @@ -3202,7 +2857,7 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-call-delegate@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + resolved "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz" integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= dependencies: babel-helper-hoist-variables "^6.24.1" @@ -3212,7 +2867,7 @@ babel-helper-call-delegate@^6.24.1: babel-helper-define-map@^6.24.1: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + resolved "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz" integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= dependencies: babel-helper-function-name "^6.24.1" @@ -3222,7 +2877,7 @@ babel-helper-define-map@^6.24.1: babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + resolved "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz" integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= dependencies: babel-runtime "^6.22.0" @@ -3231,7 +2886,7 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + resolved "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz" integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= dependencies: babel-helper-get-function-arity "^6.24.1" @@ -3242,7 +2897,7 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + resolved "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz" integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= dependencies: babel-runtime "^6.22.0" @@ -3250,7 +2905,7 @@ babel-helper-get-function-arity@^6.24.1: babel-helper-hoist-variables@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + resolved "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz" integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= dependencies: babel-runtime "^6.22.0" @@ -3258,7 +2913,7 @@ babel-helper-hoist-variables@^6.24.1: babel-helper-optimise-call-expression@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + resolved "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz" integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= dependencies: babel-runtime "^6.22.0" @@ -3266,7 +2921,7 @@ babel-helper-optimise-call-expression@^6.24.1: babel-helper-regex@^6.24.1: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + resolved "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz" integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= dependencies: babel-runtime "^6.26.0" @@ -3275,7 +2930,7 @@ babel-helper-regex@^6.24.1: babel-helper-remap-async-to-generator@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + resolved "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz" integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= dependencies: babel-helper-function-name "^6.24.1" @@ -3286,7 +2941,7 @@ babel-helper-remap-async-to-generator@^6.24.1: babel-helper-replace-supers@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + resolved "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz" integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= dependencies: babel-helper-optimise-call-expression "^6.24.1" @@ -3298,7 +2953,7 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz" integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= dependencies: babel-runtime "^6.22.0" @@ -3306,36 +2961,36 @@ babel-helpers@^6.24.1: babel-messages@^6.23.0: version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz" integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= dependencies: babel-runtime "^6.22.0" babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + resolved "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz" integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= dependencies: babel-runtime "^6.22.0" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + resolved "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz" integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + resolved "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz" integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + resolved "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz" integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= babel-plugin-transform-async-to-generator@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + resolved "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz" integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= dependencies: babel-helper-remap-async-to-generator "^6.24.1" @@ -3344,21 +2999,21 @@ babel-plugin-transform-async-to-generator@^6.22.0: babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz" integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz" integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz" integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= dependencies: babel-runtime "^6.26.0" @@ -3369,7 +3024,7 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0: babel-plugin-transform-es2015-classes@^6.23.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz" integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= dependencies: babel-helper-define-map "^6.24.1" @@ -3384,7 +3039,7 @@ babel-plugin-transform-es2015-classes@^6.23.0: babel-plugin-transform-es2015-computed-properties@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz" integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= dependencies: babel-runtime "^6.22.0" @@ -3392,14 +3047,14 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0: babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz" integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-duplicate-keys@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz" integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= dependencies: babel-runtime "^6.22.0" @@ -3407,14 +3062,14 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0: babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz" integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-function-name@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz" integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= dependencies: babel-helper-function-name "^6.24.1" @@ -3423,14 +3078,14 @@ babel-plugin-transform-es2015-function-name@^6.22.0: babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz" integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz" integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= dependencies: babel-plugin-transform-es2015-modules-commonjs "^6.24.1" @@ -3439,7 +3094,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz" integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== dependencies: babel-plugin-transform-strict-mode "^6.24.1" @@ -3449,7 +3104,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e babel-plugin-transform-es2015-modules-systemjs@^6.23.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz" integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= dependencies: babel-helper-hoist-variables "^6.24.1" @@ -3458,7 +3113,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.23.0: babel-plugin-transform-es2015-modules-umd@^6.23.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz" integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= dependencies: babel-plugin-transform-es2015-modules-amd "^6.24.1" @@ -3467,7 +3122,7 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0: babel-plugin-transform-es2015-object-super@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz" integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= dependencies: babel-helper-replace-supers "^6.24.1" @@ -3475,7 +3130,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0: babel-plugin-transform-es2015-parameters@^6.23.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz" integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= dependencies: babel-helper-call-delegate "^6.24.1" @@ -3487,7 +3142,7 @@ babel-plugin-transform-es2015-parameters@^6.23.0: babel-plugin-transform-es2015-shorthand-properties@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz" integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= dependencies: babel-runtime "^6.22.0" @@ -3495,14 +3150,14 @@ babel-plugin-transform-es2015-shorthand-properties@^6.22.0: babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz" integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-sticky-regex@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz" integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= dependencies: babel-helper-regex "^6.24.1" @@ -3511,21 +3166,21 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0: babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz" integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz" integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-unicode-regex@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz" integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= dependencies: babel-helper-regex "^6.24.1" @@ -3534,7 +3189,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0: babel-plugin-transform-exponentiation-operator@^6.22.0: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + resolved "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz" integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= dependencies: babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" @@ -3543,14 +3198,14 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + resolved "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz" integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= dependencies: regenerator-transform "^0.10.0" babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + resolved "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz" integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= dependencies: babel-runtime "^6.22.0" @@ -3558,7 +3213,7 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-preset-env@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + resolved "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz" integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== dependencies: babel-plugin-check-es2015-constants "^6.22.0" @@ -3594,7 +3249,7 @@ babel-preset-env@^1.7.0: babel-register@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + resolved "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz" integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= dependencies: babel-core "^6.26.0" @@ -3607,7 +3262,7 @@ babel-register@^6.26.0: babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" @@ -3615,7 +3270,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: babel-template@^6.24.1, babel-template@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz" integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= dependencies: babel-runtime "^6.26.0" @@ -3626,7 +3281,7 @@ babel-template@^6.24.1, babel-template@^6.26.0: babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz" integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= dependencies: babel-code-frame "^6.26.0" @@ -3641,7 +3296,7 @@ babel-traverse@^6.24.1, babel-traverse@^6.26.0: babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz" integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= dependencies: babel-runtime "^6.26.0" @@ -3651,7 +3306,7 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: babelify@^7.3.0: version "7.3.0" - resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" + resolved "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz" integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU= dependencies: babel-core "^6.0.14" @@ -3659,36 +3314,36 @@ babelify@^7.3.0: babylon@^6.18.0: version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== backoff@^2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" + resolved "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz" integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8= dependencies: precond "0.2" balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2, base-x@^3.0.8: version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== dependencies: safe-buffer "^5.0.1" base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" @@ -3701,46 +3356,46 @@ base@^0.11.1: bcrypt-pbkdf@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" + integrity "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==" dependencies: tweetnacl "^0.14.3" bech32@1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== before-after-hook@^2.2.0: version "2.2.2" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" + resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== bigint-crypto-utils@^3.0.23: version "3.1.8" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" + resolved "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz" integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== dependencies: bigint-mod-arith "^3.1.0" bigint-mod-arith@^3.1.0: version "3.1.2" - resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" + resolved "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz" integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== bignumber.js@^9.0.0: version "9.0.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" + resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz" integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bip39@2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" + resolved "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz" integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== dependencies: create-hash "^1.1.0" @@ -3751,38 +3406,33 @@ bip39@2.5.0: blakejs@^1.1.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + resolved "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== bluebird@^3.5.0, bluebird@^3.5.2, bluebird@^3.5.3: version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== bn.js@4.11.6: version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz" + integrity "sha1-UzRK2xRhehP26N0s4okF0cC6MhU= sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0: version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - -bn.js@^5.2.1: +bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.0, body-parser@^1.16.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: bytes "3.1.2" content-type "~1.0.4" @@ -3792,14 +3442,32 @@ body-parser@1.20.0, body-parser@^1.16.0: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.10.3" + qs "6.11.0" raw-body "2.5.1" type-is "~1.6.18" unpipe "1.0.0" +body-parser@^1.16.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -3807,14 +3475,14 @@ brace-expansion@^1.1.7: brace-expansion@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" braces@^2.3.1: version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" @@ -3830,19 +3498,19 @@ braces@^2.3.1: braces@^3.0.2, braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + integrity "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= 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" + resolved "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz" integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== dependencies: abstract-level "^1.0.2" @@ -3852,12 +3520,12 @@ browser-level@^1.0.1: browser-stdout@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" @@ -3869,7 +3537,7 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: browserify-cipher@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz" integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" @@ -3878,7 +3546,7 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz" integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" @@ -3888,7 +3556,7 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: bn.js "^5.0.0" @@ -3896,7 +3564,7 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: browserify-sign@^4.0.0: version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz" integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== dependencies: bn.js "^5.1.1" @@ -3911,7 +3579,7 @@ browserify-sign@^4.0.0: browserslist@^3.2.6: version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz" integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== dependencies: caniuse-lite "^1.0.30000844" @@ -3919,14 +3587,14 @@ browserslist@^3.2.6: bs58@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" + integrity "sha1-vhYedsNU9veIrkBx9j806MTwpCo= 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" + resolved "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz" integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== dependencies: bs58 "^4.0.0" @@ -3935,29 +3603,29 @@ bs58check@^2.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" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-to-arraybuffer@^0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + resolved "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz" integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= buffer-xor@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" + integrity "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" buffer-xor@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-2.0.2.tgz#34f7c64f04c777a1f8aac5e661273bb9dd320289" + resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz" integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ== dependencies: safe-buffer "^5.1.1" buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" @@ -3965,28 +3633,28 @@ buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: buffer@^6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== dependencies: base64-js "^1.3.1" ieee754 "^1.2.1" bufferutil@^4.0.1: - version "4.0.6" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" - integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== dependencies: node-gyp-build "^4.3.0" bufio@^1.0.7: version "1.2.0" - resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.2.0.tgz#b9ad1c06b0d9010363c387c39d2810a7086d143f" + resolved "https://registry.npmjs.org/bufio/-/bufio-1.2.0.tgz" integrity sha512-UlFk8z/PwdhYQTXSQQagwGAdtRI83gib2n4uy4rQnenxUM2yQi8lBDzF230BNk+3wAoZDxYRoBwVVUPgHa9MCA== builtins@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz" + integrity "sha1-y5T662HIaWRR2zZTThQi+U8K7og= sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==" busboy@^1.6.0: version "1.6.0" @@ -3997,29 +3665,29 @@ busboy@^1.6.0: byline@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= + resolved "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz" + integrity "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==" byte-size@^7.0.0: version "7.0.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-7.0.1.tgz#b1daf3386de7ab9d706b941a748dbfc71130dee3" + resolved "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz" integrity sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A== bytes@3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== bytewise-core@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" + resolved "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz" integrity sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI= dependencies: typewise-core "^1.2" bytewise@~1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" + resolved "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz" integrity sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4= dependencies: bytewise-core "^1.2.2" @@ -4027,7 +3695,7 @@ bytewise@~1.1.0: cacache@^15.0.5, cacache@^15.2.0: version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + resolved "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz" integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== dependencies: "@npmcli/fs" "^1.0.0" @@ -4051,7 +3719,7 @@ cacache@^15.0.5, cacache@^15.2.0: cache-base@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" @@ -4066,7 +3734,7 @@ cache-base@^1.0.1: cacheable-request@^6.0.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== dependencies: clone-response "^1.0.2" @@ -4079,7 +3747,7 @@ cacheable-request@^6.0.0: cachedown@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/cachedown/-/cachedown-1.0.0.tgz#d43f036e4510696b31246d7db31ebf0f7ac32d15" + resolved "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz" integrity sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU= dependencies: abstract-leveldown "^2.4.1" @@ -4087,7 +3755,7 @@ cachedown@1.0.0: call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" @@ -4095,31 +3763,31 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: caller-callsite@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + resolved "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz" + integrity "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==" dependencies: callsites "^2.0.0" caller-path@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + resolved "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz" + integrity "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==" dependencies: caller-callsite "^2.0.0" callsites@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + resolved "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz" + integrity "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==" callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase-keys@^6.2.2: version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz" integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== dependencies: camelcase "^5.3.1" @@ -4128,40 +3796,40 @@ camelcase-keys@^6.2.2: camelcase@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + resolved "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz" + integrity "sha1-MvxLn82vhF/N9+c7uXysImHwqwo= sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==" camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" 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" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30000844: - version "1.0.30001340" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001340.tgz#029a2f8bfc025d4820fafbfaa6259fd7778340c7" - integrity sha512-jUNz+a9blQTQVu4uFcn17uAD8IDizPzQkIKh3LCJfg9BkyIqExYYdyc/ZSlWUSKb8iYiXxKsxbv4zYSvkqjrxw== + version "1.0.30001457" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" + integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== cardinal@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" - integrity sha1-fMEFXYItISlU0HsIXeolHMe8VQU= + resolved "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz" + integrity "sha1-fMEFXYItISlU0HsIXeolHMe8VQU= sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==" dependencies: ansicolors "~0.3.2" redeyed "~2.1.0" caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" + integrity "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" catering@^2.1.0, catering@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + resolved "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== cbor@^8.1.0: @@ -4173,14 +3841,14 @@ cbor@^8.1.0: chai-as-promised@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" + resolved "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz" integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== dependencies: check-error "^1.0.2" chai@^4.3.4, chai@^4.3.7: version "4.3.7" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" + resolved "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz" integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== dependencies: assertion-error "^1.1.0" @@ -4193,7 +3861,7 @@ chai@^4.3.4, chai@^4.3.7: chalk@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" @@ -4204,7 +3872,7 @@ chalk@^1.1.3: chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -4213,7 +3881,7 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -4221,29 +3889,29 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: chardet@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== "charenc@>= 0.0.1": version "0.0.2" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + resolved "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz" + integrity "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" check-error@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" + integrity "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==" checkpoint-store@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" + resolved "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz" integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY= dependencies: functional-red-black-tree "^1.0.1" chokidar@3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz" integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== dependencies: anymatch "~3.1.1" @@ -4258,7 +3926,7 @@ chokidar@3.3.0: chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" @@ -4273,22 +3941,22 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: chownr@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== chownr@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== ci-info@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== cids@^0.7.1: version "0.7.5" - resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + resolved "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz" integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== dependencies: buffer "^5.5.0" @@ -4299,7 +3967,7 @@ cids@^0.7.1: 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" + resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" @@ -4307,12 +3975,12 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: class-is@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + resolved "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz" integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== class-utils@^0.3.5: version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" @@ -4322,7 +3990,7 @@ class-utils@^0.3.5: classic-level@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" + resolved "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz" integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== dependencies: abstract-level "^1.0.2" @@ -4333,26 +4001,26 @@ classic-level@^1.2.0: clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-cursor@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz" + integrity "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==" dependencies: restore-cursor "^2.0.0" cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-table3@^0.5.0: version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz" integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== dependencies: object-assign "^4.1.0" @@ -4362,7 +4030,7 @@ cli-table3@^0.5.0: cli-table3@^0.6.0: version "0.6.2" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a" + resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz" integrity sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw== dependencies: string-width "^4.2.0" @@ -4371,14 +4039,14 @@ cli-table3@^0.6.0: cli-table@^0.3.1: version "0.3.11" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.11.tgz#ac69cdecbe81dccdba4889b9a18b7da312a9d3ee" + resolved "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz" integrity sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ== dependencies: colors "1.0.3" cli-truncate@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== dependencies: slice-ansi "^3.0.0" @@ -4386,7 +4054,7 @@ cli-truncate@^2.1.0: cli-truncate@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz" integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== dependencies: slice-ansi "^5.0.0" @@ -4394,18 +4062,18 @@ cli-truncate@^3.1.0: cli-width@^2.0.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz" integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== cli-width@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== cliui@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + resolved "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz" + integrity "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==" dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -4413,7 +4081,7 @@ cliui@^3.2.0: cliui@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz" integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== dependencies: string-width "^3.1.0" @@ -4422,7 +4090,7 @@ cliui@^5.0.0: cliui@^7.0.2: version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" @@ -4431,7 +4099,7 @@ cliui@^7.0.2: clone-deep@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== dependencies: is-plain-object "^2.0.4" @@ -4440,36 +4108,36 @@ clone-deep@^4.0.1: clone-response@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= dependencies: mimic-response "^1.0.0" clone@2.1.2, clone@^2.0.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= clone@^1.0.2: version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + integrity "sha1-2jCcwmPfFZlMaIypAheco8fNfH4= sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" cmd-shim@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-4.1.0.tgz#b3a904a6743e9fede4148c6f3800bf2a08135bdd" + resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-4.1.0.tgz" integrity sha512-lb9L7EM4I/ZRVuljLPEtUJOP+xiQVknZ4ZMpMgEp4JzNldPb27HU03hi6K1/6CoIuit/Zm/LQXySErFeXxDprw== dependencies: mkdirp-infer-owner "^2.0.0" code-point-at@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" + integrity "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" collection-visit@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" @@ -4477,46 +4145,46 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^2.0.16: version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== colors@1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" + integrity "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==" colors@1.4.0, colors@^1.1.2: version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== columnify@^1.5.4: version "1.6.0" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" + resolved "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz" integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== dependencies: strip-ansi "^6.0.1" @@ -4524,19 +4192,19 @@ columnify@^1.5.4: combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" command-exists@^1.2.8: version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + resolved "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== command-line-args@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-4.0.7.tgz#f8d1916ecb90e9e121eda6428e41300bfb64cc46" + resolved "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz" integrity sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA== dependencies: array-back "^2.0.0" @@ -4545,7 +4213,7 @@ command-line-args@^4.0.7: command-line-args@^5.1.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + resolved "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz" integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== dependencies: array-back "^3.1.0" @@ -4555,7 +4223,7 @@ command-line-args@^5.1.1: command-line-usage@^6.1.0: version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + resolved "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz" integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== dependencies: array-back "^4.0.2" @@ -4565,27 +4233,27 @@ command-line-usage@^6.1.0: commander@2.18.0: version "2.18.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" + resolved "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz" 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" + resolved "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== commander@^2.19.0: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^8.3.0: version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== compare-func@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" + resolved "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz" integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== dependencies: array-ify "^1.0.0" @@ -4593,17 +4261,17 @@ compare-func@^2.0.0: component-emitter@^1.2.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2: version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== dependencies: buffer-from "^1.0.0" @@ -4613,7 +4281,7 @@ concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2: concat-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz" integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== dependencies: buffer-from "^1.0.0" @@ -4623,7 +4291,7 @@ concat-stream@^2.0.0: concurrently@^7.3.0: version "7.3.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.3.0.tgz#eb45cdbc8df43da195f619aba218a980cae49184" + resolved "https://registry.npmjs.org/concurrently/-/concurrently-7.3.0.tgz" integrity sha512-IiDwm+8DOcFEInca494A8V402tNTQlJaYq78RF2rijOrKEk/AOHTxhN4U1cp7GYKYX5Q6Ymh1dLTBlzIMN0ikA== dependencies: chalk "^4.1.0" @@ -4638,7 +4306,7 @@ concurrently@^7.3.0: config-chain@^1.1.12: version "1.1.13" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== dependencies: ini "^1.3.4" @@ -4646,8 +4314,8 @@ config-chain@^1.1.12: console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + integrity "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" content-disposition@0.5.4: version "0.5.4" @@ -4658,7 +4326,7 @@ content-disposition@0.5.4: content-hash@^2.5.2: version "2.5.2" - resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + resolved "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz" integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== dependencies: cids "^0.7.1" @@ -4667,12 +4335,17 @@ content-hash@^2.5.2: content-type@~1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + conventional-changelog-angular@^5.0.12: version "5.0.13" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" + resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz" integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== dependencies: compare-func "^2.0.0" @@ -4680,7 +4353,7 @@ conventional-changelog-angular@^5.0.12: conventional-changelog-core@^4.2.2: version "4.2.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f" + resolved "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz" integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg== dependencies: add-stream "^1.0.0" @@ -4700,12 +4373,12 @@ conventional-changelog-core@^4.2.2: conventional-changelog-preset-loader@^2.3.4: version "2.3.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c" + resolved "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz" integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g== conventional-changelog-writer@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359" + resolved "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz" integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ== dependencies: conventional-commits-filter "^2.0.7" @@ -4720,7 +4393,7 @@ conventional-changelog-writer@^5.0.0: conventional-commits-filter@^2.0.7: version "2.0.7" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3" + resolved "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz" integrity sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA== dependencies: lodash.ismatch "^4.4.0" @@ -4728,7 +4401,7 @@ conventional-commits-filter@^2.0.7: conventional-commits-parser@^3.2.0: version "3.2.4" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972" + resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz" integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q== dependencies: JSONStream "^1.0.4" @@ -4740,7 +4413,7 @@ conventional-commits-parser@^3.2.0: conventional-recommended-bump@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz#cfa623285d1de554012f2ffde70d9c8a22231f55" + resolved "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz" integrity sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw== dependencies: concat-stream "^2.0.0" @@ -4753,15 +4426,13 @@ conventional-recommended-bump@^6.1.0: q "^1.5.1" convert-source-map@^1.5.1: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.5.0: @@ -4771,42 +4442,37 @@ cookie@0.5.0: cookie@^0.4.1: version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== cookiejar@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" - integrity sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ== + version "2.1.4" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== copy-descriptor@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-pure@^3.0.1: - version "3.22.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.5.tgz#bdee0ed2f9b78f2862cda4338a07b13a49b6c9a9" - integrity sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA== + version "3.28.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.28.0.tgz#4ef2888475b6c856ef6f5aeef8b4f618b76ad048" + integrity sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ== core-js@^2.4.0, core-js@^2.5.0: version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-util-is@1.0.2: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + integrity "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" cors@^2.8.1: version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" @@ -4814,7 +4480,7 @@ cors@^2.8.1: cosmiconfig@^5.0.7: version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== dependencies: import-fresh "^2.0.0" @@ -4824,7 +4490,7 @@ cosmiconfig@^5.0.7: cosmiconfig@^7.0.0: version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz" integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== dependencies: "@types/parse-json" "^4.0.0" @@ -4835,12 +4501,12 @@ cosmiconfig@^7.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" + resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== create-ecdh@^4.0.0: version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz" integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" @@ -4848,7 +4514,7 @@ create-ecdh@^4.0.0: 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" + resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" @@ -4859,7 +4525,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" @@ -4871,7 +4537,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: create-require@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-fetch@^2.1.0, cross-fetch@^2.1.1: @@ -4891,7 +4557,7 @@ cross-fetch@^3.1.5: cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" @@ -4902,7 +4568,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -4911,12 +4577,12 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: "crypt@>= 0.0.1": version "0.0.2" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" + integrity "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" crypto-browserify@3.12.0: version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz" integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" @@ -4933,7 +4599,7 @@ crypto-browserify@3.12.0: d@1, d@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + resolved "https://registry.npmjs.org/d/-/d-1.0.1.tgz" integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== dependencies: es5-ext "^0.10.50" @@ -4941,109 +4607,109 @@ d@1, d@^1.0.1: dargs@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" + resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== dashdash@^1.12.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" + integrity "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==" dependencies: assert-plus "^1.0.0" date-fns@^2.16.1: version "2.29.1" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.1.tgz#9667c2615525e552b5135a3116b95b1961456e60" + resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.29.1.tgz" integrity sha512-dlLD5rKaKxpFdnjrs+5azHDFOPEu4ANy/LTh04A1DTzMM7qoajmKCBc8pkKRFT41CNzw+4gQh79X5C+Jq27HAw== dateformat@^3.0.0: version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== death@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" - integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= + resolved "https://registry.npmjs.org/death/-/death-1.1.0.tgz" + integrity "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==" debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@3.2.6: version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" debug@^3.1.0: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debuglog@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + resolved "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz" + integrity "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==" decamelize-keys@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz" + integrity "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==" dependencies: decamelize "^1.1.0" map-obj "^1.0.0" decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 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" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== decode-uri-component@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz" + integrity "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" decompress-response@^3.2.0, decompress-response@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: mimic-response "^1.0.0" dedent@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + integrity "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" deep-eql@^4.0.1, deep-eql@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.2.tgz#270ceb902f87724077e6f6449aed81463f42fc1c" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz" integrity sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w== dependencies: type-detect "^4.0.0" deep-equal@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz" integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== dependencies: is-arguments "^1.0.4" @@ -5055,36 +4721,36 @@ deep-equal@~1.1.1: deep-extend@~0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== defaults@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz" + integrity "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==" dependencies: clone "^1.0.2" defer-to-connect@^1.0.1: version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== deferred-leveldown@~1.2.1: version "1.2.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" + resolved "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz" integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== dependencies: abstract-leveldown "~2.6.0" deferred-leveldown@~4.0.0: version "4.0.2" - resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" + resolved "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz" integrity sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww== dependencies: abstract-leveldown "~5.0.0" @@ -5092,7 +4758,7 @@ deferred-leveldown@~4.0.0: define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== dependencies: has-property-descriptors "^1.0.0" @@ -5100,59 +4766,59 @@ define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: define-property@^0.2.5: version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= +defined@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" + integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" delegates@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + integrity "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" depd@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== depd@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" + resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== des.js@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz" integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" @@ -5165,24 +4831,24 @@ destroy@1.2.0: detect-indent@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz" integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= dependencies: repeating "^2.0.0" detect-indent@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz" + integrity "sha1-OHHMCmoALow+Wzz38zYmRnXwa50= sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==" detect-indent@^6.0.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== detect-port@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + resolved "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz" integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== dependencies: address "^1.0.1" @@ -5190,7 +4856,7 @@ detect-port@^1.3.0: dezalgo@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" + resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz" integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== dependencies: asap "^2.0.0" @@ -5198,22 +4864,22 @@ dezalgo@^1.0.0: diff@3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== diff@5.0.0, diff@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" 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" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== diffie-hellman@^5.0.0: version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz" integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" @@ -5222,92 +4888,92 @@ diffie-hellman@^5.0.0: difflib@^0.2.4: version "0.2.4" - resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" + resolved "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz" integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== dependencies: heap ">= 0.2.0" dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-walk@^0.1.0: version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== dot-prop@^5.1.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz" integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: is-obj "^2.0.0" dot-prop@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz" integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== dependencies: is-obj "^2.0.0" dotenv@^8.2.0: version "8.6.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz" integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== dotignore@~0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" + resolved "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz" integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== dependencies: minimatch "^3.0.4" duplexer3@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= duplexer@^0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== eastasianwidth@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecc-jsbn@~0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" + integrity "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==" dependencies: jsbn "~0.1.0" safer-buffer "^2.1.0" ee-first@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.47: - version "1.4.137" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz#186180a45617283f1c012284458510cd99d6787f" - integrity sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA== + version "1.4.306" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.306.tgz#3f16bc14e150ad79803145fffeaf0bee15d3fca7" + integrity sha512-1zGmLFfpcs2v7ELt/1HgLZF6Gm2CCHaAdNKxd9Ge4INSU/HDYWjs7fcWU6eVMmhkpwmh+52ZrGCUU+Ji9OJihA== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: bn.js "^4.11.9" @@ -5320,37 +4986,37 @@ elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5 emoji-regex@^10.0.0: version "10.1.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.1.0.tgz#d50e383743c0f7a5945c47087295afc112e3cf66" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz" integrity sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg== emoji-regex@^7.0.1: version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== encode-utf8@^1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + resolved "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz" integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== encodeurl@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding-down@5.0.4, encoding-down@~5.0.0: version "5.0.4" - resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" + resolved "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz" integrity sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw== dependencies: abstract-leveldown "^5.0.0" @@ -5361,57 +5027,57 @@ encoding-down@5.0.4, encoding-down@~5.0.0: encoding@^0.1.11, encoding@^0.1.12: version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: iconv-lite "^0.6.2" end-of-stream@^1.1.0: version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enquirer@^2.3.0, enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" env-paths@^2.2.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== envinfo@^7.7.4: version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== err-code@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== errno@~0.1.1: version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5: version "1.20.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.0.tgz#b2d526489cceca004588296334726329e0a6bfb6" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.0.tgz" integrity sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA== dependencies: call-bind "^1.0.2" @@ -5438,9 +5104,62 @@ es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5: string.prototype.trimstart "^1.0.5" unbox-primitive "^1.0.2" +es-abstract@^1.20.4: + version "1.21.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6" + integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.4" + is-array-buffer "^3.0.1" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.10" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -5448,9 +5167,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.61" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" - integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" @@ -5459,7 +5178,7 @@ es5-ext@^0.10.35, es5-ext@^0.10.50: es6-iterator@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== dependencies: d "1" es5-ext "^0.10.35" @@ -5467,7 +5186,7 @@ es6-iterator@^2.0.3: es6-symbol@^3.1.1, es6-symbol@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz" integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== dependencies: d "^1.0.1" @@ -5475,28 +5194,28 @@ es6-symbol@^3.1.1, es6-symbol@^3.1.3: escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" escape-string-regexp@4.0.0, 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" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@1.8.x: version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz" + integrity "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==" dependencies: esprima "^2.7.1" estraverse "^1.9.1" @@ -5507,12 +5226,12 @@ escodegen@1.8.x: eslint-config-prettier@^8.3.0: version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz" integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== eslint-scope@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== dependencies: esrecurse "^4.1.0" @@ -5520,7 +5239,7 @@ eslint-scope@^4.0.3: eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -5528,38 +5247,38 @@ eslint-scope@^5.1.1: eslint-utils@^1.3.1: version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== dependencies: eslint-visitor-keys "^1.1.0" eslint-utils@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" eslint-utils@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== dependencies: eslint-visitor-keys "^2.0.0" eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint@^5.6.0: version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + resolved "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz" integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== dependencies: "@babel/code-frame" "^7.0.0" @@ -5601,7 +5320,7 @@ eslint@^5.6.0: eslint@^7.28.0: version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + resolved "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz" integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== dependencies: "@babel/code-frame" "7.12.11" @@ -5647,7 +5366,7 @@ eslint@^7.28.0: espree@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + resolved "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz" integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== dependencies: acorn "^6.0.7" @@ -5656,7 +5375,7 @@ espree@^5.0.1: espree@^7.3.0, espree@^7.3.1: version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" @@ -5665,56 +5384,56 @@ espree@^7.3.0, espree@^7.3.1: esprima@2.7.x, esprima@^2.7.1: version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + resolved "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" + integrity "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==" esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1, esquery@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" esrecurse@^4.1.0, esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^1.9.1: version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + resolved "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz" + integrity "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-block-tracker@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz#95cd5e763c7293e0b1b2790a2a39ac2ac188a5e1" + resolved "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz" integrity sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug== dependencies: eth-query "^2.1.0" @@ -5727,15 +5446,15 @@ eth-block-tracker@^3.0.0: eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: version "2.0.8" - resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" - integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= + resolved "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz" + integrity "sha1-IprEbsqG1S4MmR58sq74P/D2i88= sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==" dependencies: idna-uts46-hx "^2.3.1" js-sha3 "^0.5.7" eth-gas-reporter@^0.2.24: version "0.2.25" - resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" + resolved "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz" integrity sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ== dependencies: "@ethersproject/abi" "^5.0.0-beta.146" @@ -5756,7 +5475,7 @@ eth-gas-reporter@^0.2.24: eth-json-rpc-infura@^3.1.0: version "3.2.1" - resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" + resolved "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz" integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== dependencies: cross-fetch "^2.1.1" @@ -5766,7 +5485,7 @@ eth-json-rpc-infura@^3.1.0: eth-json-rpc-middleware@^1.5.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" + resolved "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz" integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q== dependencies: async "^2.5.0" @@ -5785,7 +5504,7 @@ eth-json-rpc-middleware@^1.5.0: eth-lib@0.2.8: version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + resolved "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz" integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== dependencies: bn.js "^4.11.6" @@ -5794,7 +5513,7 @@ eth-lib@0.2.8: eth-lib@^0.1.26: version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + resolved "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz" integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== dependencies: bn.js "^4.11.6" @@ -5806,7 +5525,7 @@ eth-lib@^0.1.26: eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" + resolved "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz" integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4= dependencies: json-rpc-random-id "^1.0.0" @@ -5814,7 +5533,7 @@ eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: eth-sig-util@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-3.0.0.tgz#75133b3d7c20a5731af0690c385e184ab942b97e" + resolved "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.0.tgz" integrity sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ== dependencies: buffer "^5.2.1" @@ -5827,14 +5546,14 @@ eth-sig-util@3.0.0: eth-sig-util@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" - integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= + integrity sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw== dependencies: ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" ethereumjs-util "^5.1.1" eth-tx-summary@^3.1.2: version "3.2.4" - resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" + resolved "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz" integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg== dependencies: async "^2.1.2" @@ -5850,7 +5569,7 @@ eth-tx-summary@^3.1.2: ethashjs@~0.0.7: version "0.0.8" - resolved "https://registry.yarnpkg.com/ethashjs/-/ethashjs-0.0.8.tgz#227442f1bdee409a548fb04136e24c874f3aa6f9" + resolved "https://registry.npmjs.org/ethashjs/-/ethashjs-0.0.8.tgz" integrity sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw== dependencies: async "^2.1.2" @@ -5860,24 +5579,24 @@ ethashjs@~0.0.7: ethereum-bloom-filters@^1.0.6: version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" + resolved "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz" integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== dependencies: js-sha3 "^0.8.0" ethereum-common@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" + resolved "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz" integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== ethereum-common@^0.0.18: version "0.0.18" - resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" + resolved "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz" integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= 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" + resolved "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz" integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== dependencies: "@types/pbkdf2" "^3.0.0" @@ -5898,7 +5617,7 @@ ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: ethereum-cryptography@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz#b1f8f4e702434b2016248dbb2f9fdd60c54772d8" + resolved "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.0.3.tgz" integrity sha512-NQLTW0x0CosoVb/n79x/TRHtfvS3hgNUPTUSCu0vM+9k6IIhHFFrAOJReneexjZsoZxMjJHnJn4lrE8EbnSyqQ== dependencies: "@noble/hashes" "1.0.0" @@ -5908,7 +5627,7 @@ ethereum-cryptography@^1.0.3: ethereum-waffle@^3.4.4: version "3.4.4" - resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz#1378b72040697857b7f5e8f473ca8f97a37b5840" + resolved "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.4.4.tgz" integrity sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q== dependencies: "@ethereum-waffle/chai" "^3.4.4" @@ -5919,7 +5638,7 @@ ethereum-waffle@^3.4.4: ethereumjs-abi@0.6.5: version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" + resolved "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz" integrity sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE= dependencies: bn.js "^4.10.0" @@ -5927,7 +5646,7 @@ ethereumjs-abi@0.6.5: ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + resolved "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz" integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== dependencies: bn.js "^4.11.8" @@ -5942,7 +5661,7 @@ ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8: ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz#728f060c8e0c6e87f1e987f751d3da25422570a9" + resolved "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-3.0.0.tgz" integrity sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA== dependencies: ethereumjs-util "^6.0.0" @@ -5951,7 +5670,7 @@ ethereumjs-account@3.0.0, ethereumjs-account@^3.0.0: ethereumjs-account@^2.0.3: version "2.0.5" - resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" + resolved "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz" integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== dependencies: ethereumjs-util "^5.0.0" @@ -5960,7 +5679,7 @@ ethereumjs-account@^2.0.3: ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethereumjs-block@~2.2.2: version "2.2.2" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" + resolved "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz" integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== dependencies: async "^2.0.1" @@ -5971,7 +5690,7 @@ ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.0, ethere ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: version "1.7.1" - resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" + resolved "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz" integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== dependencies: async "^2.0.1" @@ -5982,7 +5701,7 @@ ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: ethereumjs-blockchain@^4.0.3: version "4.0.4" - resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz#30f2228dc35f6dcf94423692a6902604ae34960f" + resolved "https://registry.npmjs.org/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.4.tgz" integrity sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ== dependencies: async "^2.6.1" @@ -5996,19 +5715,14 @@ ethereumjs-blockchain@^4.0.3: rlp "^2.2.2" semaphore "^1.1.0" -ethereumjs-common@1.5.0: +ethereumjs-common@1.5.0, ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" + resolved "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz" integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== -ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" - integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== - ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" + resolved "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz" integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== dependencies: ethereumjs-common "^1.5.0" @@ -6016,7 +5730,7 @@ ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: version "1.3.7" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" + resolved "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz" integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== dependencies: ethereum-common "^0.0.18" @@ -6024,7 +5738,7 @@ ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@ ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0, ethereumjs-util@^6.2.1: version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + resolved "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz" integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== dependencies: "@types/bn.js" "^4.11.3" @@ -6037,7 +5751,7 @@ ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumj ethereumjs-util@^4.3.0: version "4.5.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" + resolved "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz" integrity sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w== dependencies: bn.js "^4.8.0" @@ -6048,7 +5762,7 @@ ethereumjs-util@^4.3.0: ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" + resolved "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz" integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== dependencies: bn.js "^4.11.0" @@ -6059,10 +5773,10 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum rlp "^2.0.0" safe-buffer "^5.1.1" -ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0: - version "7.1.4" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz#a6885bcdd92045b06f596c7626c3e89ab3312458" - integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== +ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.4: + version "7.1.5" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" + integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== dependencies: "@types/bn.js" "^5.1.0" bn.js "^5.1.2" @@ -6070,10 +5784,10 @@ ethereumjs-util@^7.0.2, ethereumjs-util@^7.1.0: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethereumjs-util@^7.1.4: - version "7.1.5" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" - integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== +ethereumjs-util@^7.1.0: + version "7.1.4" + resolved "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz" + integrity sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A== dependencies: "@types/bn.js" "^5.1.0" bn.js "^5.1.2" @@ -6083,7 +5797,7 @@ ethereumjs-util@^7.1.4: ethereumjs-vm@4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" + resolved "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz" integrity sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA== dependencies: async "^2.1.2" @@ -6104,7 +5818,7 @@ ethereumjs-vm@4.2.0: ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: version "2.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" + resolved "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz" integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== dependencies: async "^2.1.2" @@ -6121,7 +5835,7 @@ ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: ethereumjs-wallet@0.6.5: version "0.6.5" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" + resolved "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz" integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA== dependencies: aes-js "^3.1.1" @@ -6136,7 +5850,7 @@ ethereumjs-wallet@0.6.5: ethers@^4.0.40: version "4.0.49" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" + resolved "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz" integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== dependencies: aes-js "3.0.0" @@ -6149,45 +5863,9 @@ ethers@^4.0.40: uuid "2.0.1" xmlhttprequest "1.8.0" -ethers@^5.0.1, ethers@^5.0.2, ethers@^5.5.2: - version "5.6.5" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.5.tgz#3185ac7815dc640993408adf6f133ffabfbcbb63" - integrity sha512-9CTmplO9bv0s/aPw3HB3txGzKz3tUSI2EfO4dJo0W2WvaEq1ArgsEX6obV+bj5X3yY+Zgb1kAux8TDtJKe1FaA== - dependencies: - "@ethersproject/abi" "5.6.1" - "@ethersproject/abstract-provider" "5.6.0" - "@ethersproject/abstract-signer" "5.6.0" - "@ethersproject/address" "5.6.0" - "@ethersproject/base64" "5.6.0" - "@ethersproject/basex" "5.6.0" - "@ethersproject/bignumber" "5.6.0" - "@ethersproject/bytes" "5.6.1" - "@ethersproject/constants" "5.6.0" - "@ethersproject/contracts" "5.6.0" - "@ethersproject/hash" "5.6.0" - "@ethersproject/hdnode" "5.6.0" - "@ethersproject/json-wallets" "5.6.0" - "@ethersproject/keccak256" "5.6.0" - "@ethersproject/logger" "5.6.0" - "@ethersproject/networks" "5.6.2" - "@ethersproject/pbkdf2" "5.6.0" - "@ethersproject/properties" "5.6.0" - "@ethersproject/providers" "5.6.5" - "@ethersproject/random" "5.6.0" - "@ethersproject/rlp" "5.6.0" - "@ethersproject/sha2" "5.6.0" - "@ethersproject/signing-key" "5.6.1" - "@ethersproject/solidity" "5.6.0" - "@ethersproject/strings" "5.6.0" - "@ethersproject/transactions" "5.6.0" - "@ethersproject/units" "5.6.0" - "@ethersproject/wallet" "5.6.0" - "@ethersproject/web" "5.6.0" - "@ethersproject/wordlists" "5.6.0" - -ethers@^5.5.3, ethers@^5.7.2: +ethers@^5.0.1, ethers@^5.0.2, ethers@^5.5.2, ethers@^5.5.3, ethers@^5.7.2: version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== dependencies: "@ethersproject/abi" "5.7.0" @@ -6223,15 +5901,15 @@ ethers@^5.5.3, ethers@^5.7.2: ethjs-unit@0.1.6: version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= + resolved "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz" + integrity "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==" dependencies: bn.js "4.11.6" number-to-bn "1.7.0" ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + resolved "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz" integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== dependencies: is-hex-prefixed "1.0.0" @@ -6239,7 +5917,7 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: event-target-shim@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== eventemitter2@^6.4.5: @@ -6249,12 +5927,12 @@ eventemitter2@^6.4.5: eventemitter3@4.0.4: version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== eventemitter3@^4.0.4: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: @@ -6264,7 +5942,7 @@ events@^3.0.0: evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" @@ -6272,7 +5950,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: execa@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz" integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: cross-spawn "^6.0.0" @@ -6285,7 +5963,7 @@ execa@^1.0.0: execa@^5.0.0, execa@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -6300,7 +5978,7 @@ execa@^5.0.0, execa@^5.1.1: expand-brackets@^2.1.4: version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" @@ -6312,13 +5990,13 @@ expand-brackets@^2.1.4: to-regex "^3.0.1" express@^4.14.0: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.0" + body-parser "1.20.1" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.5.0" @@ -6337,7 +6015,7 @@ express@^4.14.0: parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.10.3" + qs "6.11.0" range-parser "~1.2.1" safe-buffer "5.2.1" send "0.18.0" @@ -6349,22 +6027,22 @@ express@^4.14.0: vary "~1.1.2" ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== dependencies: - type "^2.5.0" + type "^2.7.2" extend-shallow@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" @@ -6372,12 +6050,12 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: extend@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== external-editor@^3.0.3: version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== dependencies: chardet "^0.7.0" @@ -6386,7 +6064,7 @@ external-editor@^3.0.3: extglob@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" @@ -6405,34 +6083,29 @@ extract-files@^9.0.0: extsprintf@1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" + integrity "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" fake-merkle-patricia-tree@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" + resolved "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz" integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM= dependencies: checkpoint-store "^1.1.0" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== fast-glob@^3.0.3, fast-glob@^3.2.9: version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -6443,59 +6116,59 @@ fast-glob@^3.0.3, fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" fastq@^1.6.0: version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" fetch-ponyfill@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" + resolved "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz" integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM= dependencies: node-fetch "~1.7.1" figures@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz" + integrity "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==" dependencies: escape-string-regexp "^1.0.5" figures@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz" integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: flat-cache "^2.0.1" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" fill-range@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" @@ -6505,15 +6178,15 @@ fill-range@^4.0.0: fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" filter-obj@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= + resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz" + integrity "sha1-mzERErxsYSehbgFsbF1/GeCAXFs= sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==" finalhandler@1.2.0: version "1.2.0" @@ -6530,7 +6203,7 @@ finalhandler@1.2.0: find-replace@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" + resolved "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz" integrity sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA== dependencies: array-back "^1.0.4" @@ -6538,21 +6211,21 @@ find-replace@^1.0.3: find-replace@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + resolved "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz" integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== dependencies: array-back "^3.0.1" find-up@3.0.0, find-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: locate-path "^3.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" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -6560,22 +6233,22 @@ find-up@5.0.0: find-up@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz" + integrity "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==" dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + integrity "sha1-RdG35QbHF93UgndaK3eSCjwMV6c= sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==" dependencies: locate-path "^2.0.0" find-up@^4.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" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -6583,7 +6256,7 @@ find-up@^4.0.0, find-up@^4.1.0: find-yarn-workspace-root@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" + resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz" integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== dependencies: fs-extra "^4.0.3" @@ -6591,14 +6264,14 @@ find-yarn-workspace-root@^1.2.1: find-yarn-workspace-root@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz" integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== dependencies: micromatch "^4.0.2" flat-cache@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz" integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== dependencies: flatted "^2.0.0" @@ -6607,7 +6280,7 @@ flat-cache@^2.0.1: flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" @@ -6615,63 +6288,63 @@ flat-cache@^3.0.4: flat@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" + resolved "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz" integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== dependencies: is-buffer "~2.0.3" flat@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" 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" + resolved "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== flatted@^3.1.0: version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== flow-stoplight@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/flow-stoplight/-/flow-stoplight-1.0.0.tgz#4a292c5bcff8b39fa6cc0cb1a853d86f27eeff7b" + resolved "https://registry.npmjs.org/flow-stoplight/-/flow-stoplight-1.0.0.tgz" integrity sha1-SiksW8/4s5+mzAyxqFPYbyfu/3s= fmix@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/fmix/-/fmix-0.1.0.tgz#c7bbf124dec42c9d191cfb947d0a9778dd986c0c" - integrity sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw= + resolved "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz" + integrity "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw= sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==" dependencies: imul "^1.0.0" follow-redirects@^1.12.1, follow-redirects@^1.14.0: version "1.15.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz" integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ== for-each@^0.3.3, for-each@~0.3.3: version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" for-in@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= forever-agent@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" + integrity "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" form-data@^2.2.0: version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== dependencies: asynckit "^0.4.0" @@ -6680,7 +6353,7 @@ form-data@^2.2.0: form-data@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" @@ -6689,7 +6362,7 @@ form-data@^3.0.0: form-data@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" @@ -6698,7 +6371,7 @@ form-data@^4.0.0: form-data@~2.3.2: version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== dependencies: asynckit "^0.4.0" @@ -6710,32 +6383,27 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fp-ts@1.19.3: +fp-ts@1.19.3, fp-ts@^1.0.0: version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" + resolved "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz" integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - fragment-cache@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= fs-extra@^0.30.0: version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz" + integrity "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==" dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -6745,7 +6413,7 @@ fs-extra@^0.30.0: fs-extra@^10.0.0: version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" @@ -6754,7 +6422,7 @@ fs-extra@^10.0.0: fs-extra@^4.0.2, fs-extra@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz" integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== dependencies: graceful-fs "^4.1.2" @@ -6763,7 +6431,7 @@ fs-extra@^4.0.2, fs-extra@^4.0.3: fs-extra@^7.0.0, fs-extra@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz" integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== dependencies: graceful-fs "^4.1.2" @@ -6772,7 +6440,7 @@ fs-extra@^7.0.0, fs-extra@^7.0.1: fs-extra@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: graceful-fs "^4.2.0" @@ -6781,7 +6449,7 @@ fs-extra@^8.1.0: fs-extra@^9.1.0: version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" @@ -6791,46 +6459,46 @@ fs-extra@^9.1.0: fs-minipass@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz" integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: minipass "^2.6.0" fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== dependencies: minipass "^3.0.0" fs-readdir-recursive@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + resolved "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz" integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@~2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== fsevents@~2.3.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== function.prototype.name@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== dependencies: call-bind "^1.0.2" @@ -6840,17 +6508,17 @@ function.prototype.name@^1.1.5: functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + integrity "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" functions-have-names@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== ganache-core@^2.13.2: version "2.13.2" - resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.2.tgz#27e6fc5417c10e6e76e2e646671869d7665814a3" + resolved "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz" integrity sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw== dependencies: abstract-leveldown "3.0.0" @@ -6887,8 +6555,8 @@ ganache-core@^2.13.2: gauge@~2.7.3: version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" + integrity "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==" dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -6901,31 +6569,40 @@ gauge@~2.7.3: get-caller-file@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-func-name@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" + integrity "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==" get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-pkg-repo@^4.0.0: version "4.2.1" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" + resolved "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz" integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== dependencies: "@hutson/parse-repository-url" "^3.0.0" @@ -6935,41 +6612,41 @@ get-pkg-repo@^4.0.0: get-port@^3.1.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + resolved "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz" + integrity "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" get-port@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + resolved "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== get-stream@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" get-stream@^5.1.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== get-symbol-description@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: call-bind "^1.0.2" @@ -6977,19 +6654,19 @@ get-symbol-description@^1.0.0: get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= getpass@^0.1.1: version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" + integrity "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==" dependencies: assert-plus "^1.0.0" ghost-testrpc@^0.0.2: version "0.0.2" - resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" + resolved "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz" integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== dependencies: chalk "^2.4.2" @@ -6997,7 +6674,7 @@ ghost-testrpc@^0.0.2: git-raw-commits@^2.0.8: version "2.0.11" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" + resolved "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz" integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A== dependencies: dargs "^7.0.0" @@ -7008,15 +6685,15 @@ git-raw-commits@^2.0.8: git-remote-origin-url@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= + resolved "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz" + integrity "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==" dependencies: gitconfiglocal "^1.0.0" pify "^2.3.0" git-semver-tags@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-4.1.1.tgz#63191bcd809b0ec3e151ba4751c16c444e5b5780" + resolved "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz" integrity sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA== dependencies: meow "^8.0.0" @@ -7024,7 +6701,7 @@ git-semver-tags@^4.1.1: git-up@^4.0.0: version "4.0.5" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.5.tgz#e7bb70981a37ea2fb8fe049669800a1f9a01d759" + resolved "https://registry.npmjs.org/git-up/-/git-up-4.0.5.tgz" integrity sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA== dependencies: is-ssh "^1.3.0" @@ -7032,28 +6709,28 @@ git-up@^4.0.0: git-url-parse@^11.4.4: version "11.6.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.6.0.tgz#c634b8de7faa66498a2b88932df31702c67df605" + resolved "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.6.0.tgz" integrity sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g== dependencies: git-up "^4.0.0" gitconfiglocal@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= + resolved "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz" + integrity "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==" dependencies: ini "^1.3.2" glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob@7.1.3: version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" @@ -7065,7 +6742,7 @@ glob@7.1.3: glob@7.1.7: version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" @@ -7075,9 +6752,9 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.2.0, glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.2.0: +glob@7.2.0, glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" @@ -7089,8 +6766,8 @@ glob@7.2.0, glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glo glob@^5.0.15: version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + resolved "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz" + integrity "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==" dependencies: inflight "^1.0.4" inherits "2" @@ -7098,7 +6775,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.6: +glob@~7.2.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -7112,14 +6789,14 @@ glob@^7.1.6: global-modules@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz" integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== dependencies: global-prefix "^3.0.0" global-prefix@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz" integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== dependencies: ini "^1.3.5" @@ -7128,7 +6805,7 @@ global-prefix@^3.0.0: global@~4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + resolved "https://registry.npmjs.org/global/-/global-4.4.0.tgz" integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== dependencies: min-document "^2.19.0" @@ -7136,24 +6813,31 @@ global@~4.4.0: globals@^11.7.0: version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: version "13.15.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.15.0.tgz#38113218c907d2f7e98658af246cef8b77e90bac" + resolved "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz" integrity sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog== dependencies: type-fest "^0.20.2" globals@^9.18.0: version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz" integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^10.0.1: version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + resolved "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz" integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== dependencies: "@types/glob" "^7.1.1" @@ -7167,7 +6851,7 @@ globby@^10.0.1: globby@^11.0.2, globby@^11.0.3: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -7177,9 +6861,16 @@ globby@^11.0.2, globby@^11.0.3: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + got@9.6.0: version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + resolved "https://registry.npmjs.org/got/-/got-9.6.0.tgz" integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== dependencies: "@sindresorhus/is" "^0.14.0" @@ -7196,7 +6887,7 @@ got@9.6.0: got@^7.1.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + resolved "https://registry.npmjs.org/got/-/got-7.1.0.tgz" integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== dependencies: decompress-response "^3.2.0" @@ -7216,7 +6907,7 @@ got@^7.1.0: graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3: version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== graphql-request@^5.2.0: @@ -7236,12 +6927,12 @@ graphql@^16.6.0: growl@1.10.5: version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== handlebars@^4.0.1, handlebars@^4.7.7: version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== dependencies: minimist "^1.2.5" @@ -7253,12 +6944,12 @@ handlebars@^4.0.1, handlebars@^4.7.7: har-schema@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" + integrity "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" har-validator@~5.1.3: version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: ajv "^6.12.3" @@ -7266,12 +6957,12 @@ har-validator@~5.1.3: hard-rejection@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" + resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== hardhat-contract-sizer@^2.4.0: version "2.5.1" - resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.5.1.tgz#cb0b8dd32593b7a28c8d96ecde04841292bbd603" + resolved "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.5.1.tgz" integrity sha512-28yRb73e30aBVaZOOHTlHZFIdIasA/iFunIehrUviIJTubvdQjtSiQUo2wexHFtt71mQeMPP8qjw2sdbgatDnQ== dependencies: chalk "^4.0.0" @@ -7279,12 +6970,12 @@ hardhat-contract-sizer@^2.4.0: hardhat-dependency-compiler@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.2.tgz#02867b7c6dd3de4924d9d3d6593feab8408f1eeb" + resolved "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.2.tgz" integrity sha512-LVnsPSZnGvzWVvlpewlkPKlPtFP/S9V41RC1fd/ygZc4jkG8ubNlfE82nwiGw5oPueHSmFi6TACgmyrEOokK8w== hardhat-deploy@^0.11.4: version "0.11.22" - resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.22.tgz#9799c0266a0fc40c84690de54760f1b4dae5e487" + resolved "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.11.22.tgz" integrity sha512-ZhHVNB7Jo2l8Is+KIAk9F8Q3d7pptyiX+nsNbIFXztCz81kaP+6kxNODRBqRCy7SOD3It4+iKCL6tWsPAA/jVQ== dependencies: "@types/qs" "^6.9.7" @@ -7303,7 +6994,7 @@ hardhat-deploy@^0.11.4: hardhat-gas-reporter@^1.0.4: version "1.0.8" - resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz#93ce271358cd748d9c4185dbb9d1d5525ec145e0" + resolved "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz" integrity sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g== dependencies: array-uniq "1.0.3" @@ -7312,7 +7003,7 @@ hardhat-gas-reporter@^1.0.4: hardhat@^2.12.2: version "2.12.5" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.5.tgz#e3cd4d6dae35cb9505055967bd7e15e6adf3aa03" + resolved "https://registry.npmjs.org/hardhat/-/hardhat-2.12.5.tgz" integrity sha512-f/t7+hLlhsnQZ6LDXyV+8rHGRZFZY1sgFvgrwr9fBjMdGp1Bu6hHq1KXS4/VFZfZcVdL1DAWWEkryinZhqce+A== dependencies: "@ethersproject/abi" "^5.1.2" @@ -7368,75 +7059,80 @@ hardhat@^2.12.2: has-ansi@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + resolved "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz" + integrity "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==" has-flag@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= + resolved "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz" + integrity "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==" has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== dependencies: get-intrinsic "^1.1.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbol-support-x@^1.4.1: version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + resolved "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz" integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-to-string-tag-x@^1.2.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + resolved "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz" integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== dependencies: has-symbol-support-x "^1.4.1" has-tostringtag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== dependencies: has-symbols "^1.0.2" has-unicode@^2.0.0, has-unicode@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + integrity "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" has-value@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" @@ -7445,7 +7141,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" @@ -7454,12 +7150,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" @@ -7467,14 +7163,14 @@ has-values@^1.0.0: has@^1.0.3, has@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hash-base@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz" integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: inherits "^2.0.4" @@ -7483,7 +7179,7 @@ hash-base@^3.0.0: hash.js@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz" integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== dependencies: inherits "^2.0.3" @@ -7491,7 +7187,7 @@ hash.js@1.1.3: 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" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" @@ -7499,23 +7195,23 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== heap@0.2.6: version "0.2.6" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" + resolved "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz" integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw= "heap@>= 0.2.0": version "0.2.7" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" + resolved "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz" integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + integrity "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==" dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" @@ -7523,7 +7219,7 @@ hmac-drbg@^1.0.1: home-or-tmp@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz" integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= dependencies: os-homedir "^1.0.0" @@ -7531,19 +7227,19 @@ home-or-tmp@^2.0.0: hosted-git-info@^2.1.4, hosted-git-info@^2.6.0: version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" http-basic@^8.1.1: version "8.1.3" - resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" + resolved "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz" integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw== dependencies: caseless "^0.12.0" @@ -7553,12 +7249,12 @@ http-basic@^8.1.1: http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== http-errors@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: depd "2.0.0" @@ -7569,12 +7265,12 @@ http-errors@2.0.0: http-https@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + resolved "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz" integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= http-proxy-agent@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: "@tootallnate/once" "1" @@ -7583,15 +7279,15 @@ http-proxy-agent@^4.0.1: http-response-object@^3.0.1: version "3.0.2" - resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" + resolved "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz" integrity sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA== dependencies: "@types/node" "^10.0.3" http-signature@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" + integrity "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==" dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -7599,7 +7295,7 @@ http-signature@~1.2.0: https-proxy-agent@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" @@ -7607,90 +7303,85 @@ https-proxy-agent@^5.0.0: human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== humanize-ms@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" + integrity "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==" dependencies: ms "^2.0.0" husky@>=6: version "8.0.1" - resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9" + resolved "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz" integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== 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" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.6.2: version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" idna-uts46-hx@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + resolved "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz" integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== dependencies: punycode "2.1.0" ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore-walk@^3.0.3: version "3.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" + resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz" integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== dependencies: minimatch "^3.0.4" ignore@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -immediate@^3.2.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" - integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== - -immediate@~3.2.3: +immediate@^3.2.3, immediate@~3.2.3: version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + resolved "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz" integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= immutable@^4.0.0-rc.12: version "4.0.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + resolved "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz" integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== import-fresh@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz" + integrity "sha1-2BNVwVYS04bGH53dOSLUMEgipUY= sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==" dependencies: caller-path "^2.0.0" resolve-from "^3.0.0" import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -7698,7 +7389,7 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: import-local@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: pkg-dir "^4.2.0" @@ -7706,27 +7397,27 @@ import-local@^3.0.2: imul@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9" - integrity sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk= + resolved "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz" + integrity "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk= sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==" imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity "sha1-khi5srkoojixPcT7a21XbyMUU+o= sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== infer-owner@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -7734,17 +7425,17 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@^1.3.2, ini@^1.3.4, ini@^1.3.5: version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== init-package-json@^2.0.2: version "2.0.5" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-2.0.5.tgz#78b85f3c36014db42d8f32117252504f68022646" + resolved "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.5.tgz" integrity sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA== dependencies: npm-package-arg "^8.1.5" @@ -7757,7 +7448,7 @@ init-package-json@^2.0.2: inquirer@^6.2.2: version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz" integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: ansi-escapes "^3.2.0" @@ -7776,7 +7467,7 @@ inquirer@^6.2.2: inquirer@^7.3.3: version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz" integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== dependencies: ansi-escapes "^4.2.1" @@ -7795,57 +7486,66 @@ inquirer@^7.3.3: internal-slot@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== dependencies: get-intrinsic "^1.1.0" has "^1.0.3" side-channel "^1.0.4" +internal-slot@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + interpret@^1.0.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== invariant@^2.2.2: version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" invert-kv@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" + integrity "sha1-EEqOSqym09jNFXqO+L+rLXo//bY= sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==" io-ts@1.10.4: version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" + resolved "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz" integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== dependencies: fp-ts "^1.0.0" ip@^1.1.5: version "1.1.8" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + resolved "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz" integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== ipaddr.js@1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-accessor-descriptor@^0.1.6: version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" @@ -7858,28 +7558,37 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-array-buffer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" + integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-typed-array "^1.1.10" + is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" @@ -7887,57 +7596,69 @@ is-boolean-object@^1.1.0: is-buffer@^1.1.5: version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-buffer@^2.0.5, is-buffer@~2.0.3: version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: +is-callable@^1.1.3, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== is-ci@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + resolved "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz" integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== dependencies: ci-info "^2.0.0" -is-core-module@^2.5.0, is-core-module@^2.8.1: +is-core-module@^2.5.0: version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz" integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" is-descriptor@^0.1.0: version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" @@ -7946,7 +7667,7 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" @@ -7955,144 +7676,144 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-directory@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz" + integrity "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==" is-docker@^2.0.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" is-finite@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== is-fn@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" + resolved "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz" integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= is-fullwidth-code-point@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + integrity "sha1-754xOG8DGn8NZDr4L95QxFfvAMs= sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==" dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + integrity "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-fullwidth-code-point@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== is-function@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + resolved "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz" integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== is-glob@^4.0.0, 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" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 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 sha1-fY035q135dEnFIkTxXPggtd39VQ= + resolved "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz" + integrity "sha1-fY035q135dEnFIkTxXPggtd39VQ= sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==" is-lambda@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= + resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" + integrity "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" is-negative-zero@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" is-number@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-object@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + resolved "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz" integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" + integrity "sha1-caUMhCnfync8kqOQpKA7OfzVHT4= sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" is-plain-obj@^2.0.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" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-plain-object@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -8100,128 +7821,139 @@ is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: is-retry-allowed@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz" integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== is-shared-array-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== dependencies: call-bind "^1.0.2" is-ssh@^1.3.0: version "1.3.3" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.3.tgz#7f133285ccd7f2c2c7fc897b771b53d95a2b2c7e" + resolved "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz" integrity sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ== dependencies: protocols "^1.1.0" is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" + integrity "sha1-EtSj3U5o4Lec6428hBc66A2RykQ= sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-text-path@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + resolved "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz" + integrity "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==" dependencies: text-extensions "^1.0.0" +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + integrity "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== is-url@^1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + resolved "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz" integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== is-utf8@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" + integrity "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==" is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" is-windows@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== is-wsl@^2.1.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" isarray@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= isarray@1.0.0, isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" isobject@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + integrity "sha1-TkMekrEalzFjaqH5yNHMvP2reN8= sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" isstream@~0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + integrity "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" isurl@^1.0.0-alpha5: version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + resolved "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz" integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== dependencies: has-to-string-tag-x "^1.2.0" @@ -8234,27 +7966,27 @@ js-base64@^3.7.2: js-sha3@0.5.7, js-sha3@^0.5.7: version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= + resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz" + integrity "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==" js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-tokens@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= js-yaml@3.13.1: version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== dependencies: argparse "^1.0.7" @@ -8262,7 +7994,7 @@ js-yaml@3.13.1: js-yaml@3.x, 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" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -8270,44 +8002,44 @@ js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1: js-yaml@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" jsbn@~0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" + integrity "sha1-peZUwuWi3rXyAdls77yoDA7y9RM= sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" jsesc@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz" integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= jsesc@~0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= json-buffer@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= 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" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: version "3.8.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" + resolved "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz" integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== dependencies: async "^2.0.1" @@ -8319,75 +8051,75 @@ json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: json-rpc-error@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" + resolved "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz" integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI= dependencies: inherits "^2.0.1" json-rpc-random-id@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" + resolved "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz" integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-schema@0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" json-stable-stringify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= dependencies: jsonify "~0.0.0" json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + integrity "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" json5@^0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + resolved "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= json5@^2.1.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== jsonfile@^2.1.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz" + integrity "sha1-NzaitCi4e72gzIO1P6PWM6NcKug= 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" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" 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" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: universalify "^2.0.0" @@ -8396,22 +8128,22 @@ jsonfile@^6.0.1: jsonify@~0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + resolved "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsonparse@^1.2.0, jsonparse@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" + integrity "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" jsonschema@^1.2.4: version "1.4.0" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2" + resolved "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz" integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw== jsprim@^1.2.2: version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== dependencies: assert-plus "1.0.0" @@ -8421,85 +8153,76 @@ jsprim@^1.2.2: keccak@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + resolved "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz" integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== dependencies: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" -keccak@^3.0.0: +keccak@^3.0.0, keccak@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.2.tgz#4c2c6e8c54e04f2670ee49fa734eb9da152206e0" + resolved "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz" integrity sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ== dependencies: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" readable-stream "^3.6.0" -keccak@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" - integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - keyv@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== dependencies: json-buffer "3.0.0" kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== klaw-sync@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + resolved "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz" integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== dependencies: graceful-fs "^4.1.11" klaw@^1.0.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + resolved "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz" + integrity "sha1-QIhDO0azsbolnXh4XY6W9zugJDk= sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==" optionalDependencies: graceful-fs "^4.1.9" lcid@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + resolved "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz" + integrity "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==" dependencies: invert-kv "^1.0.0" lerna@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-4.0.0.tgz#b139d685d50ea0ca1be87713a7c2f44a5b678e9e" + resolved "https://registry.npmjs.org/lerna/-/lerna-4.0.0.tgz" integrity sha512-DD/i1znurfOmNJb0OBw66NmNqiM8kF6uIrzrJ0wGE3VNdzeOhz9ziWLYiRaZDGGwgbcjOo6eIfcx9O5Qynz+kg== dependencies: "@lerna/add" "4.0.0" @@ -8523,40 +8246,33 @@ lerna@^4.0.0: level-codec@^9.0.0: version "9.0.2" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" + resolved "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz" integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== dependencies: buffer "^5.6.0" level-codec@~7.0.0: version "7.0.1" - resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" + resolved "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz" integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== -level-errors@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" - integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== +level-errors@^1.0.3, level-errors@~1.0.3: + version "1.0.5" + resolved "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz" + integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== dependencies: errno "~0.1.1" level-errors@^2.0.0, level-errors@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + resolved "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz" integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== dependencies: errno "~0.1.1" -level-errors@~1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" - integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== - dependencies: - errno "~0.1.1" - level-iterator-stream@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" + resolved "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz" integrity sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig== dependencies: inherits "^2.0.1" @@ -8565,7 +8281,7 @@ level-iterator-stream@^2.0.3: level-iterator-stream@~1.3.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" + resolved "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz" integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= dependencies: inherits "^2.0.1" @@ -8575,7 +8291,7 @@ level-iterator-stream@~1.3.0: level-iterator-stream@~3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" + resolved "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz" integrity sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g== dependencies: inherits "^2.0.1" @@ -8584,7 +8300,7 @@ level-iterator-stream@~3.0.0: level-mem@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5" + resolved "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz" integrity sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg== dependencies: level-packager "~4.0.0" @@ -8592,7 +8308,7 @@ level-mem@^3.0.1: level-packager@~4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6" + resolved "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz" integrity sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q== dependencies: encoding-down "~5.0.0" @@ -8600,14 +8316,14 @@ level-packager@~4.0.0: level-post@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" + resolved "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz" integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== dependencies: ltgt "^2.1.2" level-sublevel@6.6.4: version "6.6.4" - resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.4.tgz#f7844ae893919cd9d69ae19d7159499afd5352ba" + resolved "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz" integrity sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA== dependencies: bytewise "~1.1.0" @@ -8623,12 +8339,12 @@ level-sublevel@6.6.4: level-supports@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + resolved "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz" 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" + resolved "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz" integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== dependencies: buffer "^6.0.3" @@ -8636,7 +8352,7 @@ level-transcoder@^1.0.1: level-ws@0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" + resolved "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz" integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos= dependencies: readable-stream "~1.0.15" @@ -8644,7 +8360,7 @@ level-ws@0.0.0: level-ws@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" + resolved "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz" integrity sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q== dependencies: inherits "^2.0.3" @@ -8653,7 +8369,7 @@ level-ws@^1.0.0: level@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" + resolved "https://registry.npmjs.org/level/-/level-8.0.0.tgz" integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== dependencies: browser-level "^1.0.1" @@ -8661,7 +8377,7 @@ level@^8.0.0: levelup@3.1.1, levelup@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" + resolved "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz" integrity sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg== dependencies: deferred-leveldown "~4.0.0" @@ -8671,7 +8387,7 @@ levelup@3.1.1, levelup@^3.0.0: levelup@^1.2.1: version "1.3.9" - resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" + resolved "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz" integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== dependencies: deferred-leveldown "~1.2.1" @@ -8684,15 +8400,15 @@ levelup@^1.2.1: levn@^0.3.0, levn@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" + integrity "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==" dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -8700,7 +8416,7 @@ levn@^0.4.1: libnpmaccess@^4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-4.0.3.tgz#dfb0e5b0a53c315a2610d300e46b4ddeb66e7eec" + resolved "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-4.0.3.tgz" integrity sha512-sPeTSNImksm8O2b6/pf3ikv4N567ERYEpeKRPSmqlNt1dTZbvgpJIzg5vAhXHpw2ISBsELFRelk0jEahj1c6nQ== dependencies: aproba "^2.0.0" @@ -8710,7 +8426,7 @@ libnpmaccess@^4.0.1: libnpmpublish@^4.0.0: version "4.0.2" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-4.0.2.tgz#be77e8bf5956131bcb45e3caa6b96a842dec0794" + resolved "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-4.0.2.tgz" integrity sha512-+AD7A2zbVeGRCFI2aO//oUmapCwy7GHqPXFJh3qpToSRNU+tXKJ2YFUgjt04LPPAf2dlEH95s6EhIHM1J7bmOw== dependencies: normalize-package-data "^3.0.2" @@ -8721,17 +8437,17 @@ libnpmpublish@^4.0.0: lilconfig@2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz" integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lint-staged@>=10: version "12.4.1" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.4.1.tgz#63fa27bfc8a33515f6902f63f6670864f1fb233c" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-12.4.1.tgz" integrity sha512-PTXgzpflrQ+pODQTG116QNB+Q6uUTDg5B5HqGvNhoQSGt8Qy+MA/6zSnR8n38+sxP5TapzeQGTvoKni0KRS8Vg== dependencies: cli-truncate "^3.1.0" @@ -8751,7 +8467,7 @@ lint-staged@>=10: listr2@^4.0.1: version "4.0.5" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.5.tgz#9dcc50221583e8b4c71c43f9c7dfd0ef546b75d5" + resolved "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz" integrity sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA== dependencies: cli-truncate "^2.1.0" @@ -8765,8 +8481,8 @@ listr2@^4.0.1: load-json-file@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" + integrity "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==" dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -8776,8 +8492,8 @@ load-json-file@^1.0.0: load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" + integrity "sha1-L19Fq5HjMhYjT9U62rZo607AmTs= sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==" dependencies: graceful-fs "^4.1.2" parse-json "^4.0.0" @@ -8786,7 +8502,7 @@ load-json-file@^4.0.0: load-json-file@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz" integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== dependencies: graceful-fs "^4.1.15" @@ -8796,15 +8512,15 @@ load-json-file@^6.2.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 sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + integrity "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==" dependencies: p-locate "^2.0.0" path-exists "^3.0.0" locate-path@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: p-locate "^3.0.0" @@ -8812,56 +8528,56 @@ locate-path@^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" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash._reinterpolate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" + integrity "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + resolved "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz" + integrity "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" lodash.camelcase@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== lodash.isequal@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz" + integrity "sha1-QVxEePK8wwEgwizhDtMib30+GOA= sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" lodash.isequalwith@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.isequalwith/-/lodash.isequalwith-4.4.0.tgz#266726ddd528f854f21f4ea98a065606e0fbc6b0" - integrity sha1-Jmcm3dUo+FTyH06pigZWBuD7xrA= + resolved "https://registry.npmjs.org/lodash.isequalwith/-/lodash.isequalwith-4.4.0.tgz" + integrity "sha1-Jmcm3dUo+FTyH06pigZWBuD7xrA= sha512-dcZON0IalGBpRmJBmMkaoV7d3I80R2O+FrzsZyHdNSFrANq/cgDqKQNmAHE8UEj4+QYWwwhkQOVdLHiAopzlsQ==" lodash.ismatch@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= + resolved "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz" + integrity "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.template@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz" integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== dependencies: lodash._reinterpolate "^3.0.0" @@ -8869,36 +8585,36 @@ lodash.template@^4.5.0: lodash.templatesettings@^4.0.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz" integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== dependencies: lodash._reinterpolate "^3.0.0" lodash.truncate@^4.4.2: version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" + integrity "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" -lodash@4.17.20: +lodash@4.17.20, lodash@^4.17.4: version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz" integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== dependencies: chalk "^2.4.2" log-symbols@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -8906,7 +8622,7 @@ log-symbols@4.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" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: ansi-escapes "^4.3.0" @@ -8916,77 +8632,77 @@ log-update@^4.0.0: looper@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" + resolved "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz" integrity sha1-Zs0Md0rz1P7axTeU90LbVtqPCew= looper@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" + resolved "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz" integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= loose-envify@^1.0.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" 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.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" + resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== dependencies: get-func-name "^2.0.0" lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== lowercase-keys@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== lru-cache@5.1.1, lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" lru-cache@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz" integrity sha1-cXibO39Tmb7IVl3aOKow0qCX7+4= dependencies: pseudomap "^1.0.1" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" lru_map@^0.3.3: version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= - -ltgt@^2.1.2, ltgt@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" - integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= + resolved "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz" + integrity "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" -ltgt@~2.1.1: +ltgt@^2.1.2, ltgt@~2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" + resolved "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz" integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= +ltgt@~2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz" + integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= + make-dir@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== dependencies: pify "^4.0.1" @@ -8994,19 +8710,19 @@ make-dir@^2.1.0: make-dir@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" make-error@^1.1.1: version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== make-fetch-happen@^8.0.9: version "8.0.14" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz" integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== dependencies: agentkeepalive "^4.1.3" @@ -9027,7 +8743,7 @@ make-fetch-happen@^8.0.9: make-fetch-happen@^9.0.1: version "9.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz" integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== dependencies: agentkeepalive "^4.1.3" @@ -9049,34 +8765,34 @@ make-fetch-happen@^9.0.1: map-cache@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-obj@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" + integrity "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==" map-obj@^4.0.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== map-visit@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" markdown-table@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" + resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== marked-terminal@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-3.3.0.tgz#25ce0c0299285998c7636beaefc87055341ba1bd" + resolved "https://registry.npmjs.org/marked-terminal/-/marked-terminal-3.3.0.tgz" integrity sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A== dependencies: ansi-escapes "^3.1.0" @@ -9088,22 +8804,22 @@ marked-terminal@^3.3.0: marked@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" + resolved "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz" integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== match-all@^1.2.6: version "1.2.6" - resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" + resolved "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz" integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== mcl-wasm@^0.7.1: version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" + resolved "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz" 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" + resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz" integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" @@ -9112,12 +8828,12 @@ md5.js@^1.3.4: media-typer@0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= memdown@^1.0.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" + resolved "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz" integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= dependencies: abstract-leveldown "~2.7.1" @@ -9129,7 +8845,7 @@ memdown@^1.0.0: memdown@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" + resolved "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz" integrity sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA== dependencies: abstract-leveldown "~5.0.0" @@ -9141,7 +8857,7 @@ memdown@~3.0.0: memory-level@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" + resolved "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz" integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== dependencies: abstract-level "^1.0.0" @@ -9150,12 +8866,12 @@ memory-level@^1.0.0: memorystream@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz" + integrity "sha1-htcJCzDORV1j+64S3aUaR93K+bI= sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==" meow@^8.0.0: version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" + resolved "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz" integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== dependencies: "@types/minimist" "^1.2.0" @@ -9172,22 +8888,22 @@ meow@^8.0.0: merge-descriptors@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== merkle-patricia-tree@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" + resolved "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz" integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== dependencies: async "^2.6.1" @@ -9200,7 +8916,7 @@ merkle-patricia-tree@3.0.0: merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" + resolved "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz" integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== dependencies: async "^1.4.2" @@ -9214,12 +8930,12 @@ merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: methods@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^3.1.4: version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" @@ -9238,7 +8954,7 @@ micromatch@^3.1.4: micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -9246,7 +8962,7 @@ micromatch@^4.0.2, micromatch@^4.0.4: miller-rabin@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz" integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" @@ -9254,103 +8970,108 @@ miller-rabin@^4.0.0: mime-db@1.52.0: version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mime@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== min-document@^2.19.0: version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + resolved "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz" integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= dependencies: dom-walk "^0.1.0" min-indent@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" 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" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" 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 sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + integrity "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" "minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" minimatch@3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimatch@5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: brace-expansion "^2.0.1" minimist-options@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" + resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz" integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== dependencies: arrify "^1.0.1" is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.6: +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +minimist@~1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + minipass-collect@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== dependencies: minipass "^3.0.0" minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: version "1.4.1" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" + resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz" integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== dependencies: minipass "^3.1.0" @@ -9361,14 +9082,14 @@ minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: minipass-flush@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== dependencies: minipass "^3.0.0" minipass-json-stream@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + resolved "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz" integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== dependencies: jsonparse "^1.3.1" @@ -9376,21 +9097,21 @@ minipass-json-stream@^1.0.1: minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" minipass-sized@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== dependencies: minipass "^3.0.0" minipass@^2.6.0, minipass@^2.9.0: version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + resolved "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" @@ -9398,21 +9119,21 @@ minipass@^2.6.0, minipass@^2.9.0: minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz" integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== dependencies: yallist "^4.0.0" minizlib@^1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz" integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== dependencies: minipass "^2.9.0" minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== dependencies: minipass "^3.0.0" @@ -9420,7 +9141,7 @@ minizlib@^2.0.0, minizlib@^2.1.1: mixin-deep@^1.2.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" @@ -9428,7 +9149,7 @@ mixin-deep@^1.2.0: mkdirp-infer-owner@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316" + resolved "https://registry.npmjs.org/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz" integrity sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw== dependencies: chownr "^2.0.0" @@ -9437,40 +9158,45 @@ mkdirp-infer-owner@^2.0.0: mkdirp-promise@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + resolved "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz" integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= dependencies: mkdirp "*" -mkdirp@*, mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@*: + version "2.1.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.3.tgz#b083ff37be046fd3d6552468c1f0ff44c1545d1f" + integrity sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw== mkdirp@0.5.5: version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mnemonist@^0.38.0: version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" + resolved "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz" integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== dependencies: obliterator "^2.0.0" mocha@7.1.2: version "7.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" + resolved "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz" integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== dependencies: ansi-colors "3.2.3" @@ -9500,7 +9226,7 @@ mocha@7.1.2: mocha@^10.0.0: version "10.0.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" + resolved "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz" integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== dependencies: "@ungap/promise-all-settled" "1.1.2" @@ -9528,7 +9254,7 @@ mocha@^10.0.0: mocha@^7.1.1: version "7.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" + resolved "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz" integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== dependencies: ansi-colors "3.2.3" @@ -9563,37 +9289,37 @@ mock-fs@^4.1.0: modify-values@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== 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" + resolved "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz" integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== ms@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" ms@2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== ms@2.1.3, ms@^2.0.0, ms@^2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== multibase@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + resolved "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz" integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== dependencies: base-x "^3.0.8" @@ -9601,7 +9327,7 @@ multibase@^0.7.0: multibase@~0.6.0: version "0.6.1" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + resolved "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz" integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== dependencies: base-x "^3.0.8" @@ -9609,14 +9335,14 @@ multibase@~0.6.0: multicodec@^0.5.5: version "0.5.7" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + resolved "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz" integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== dependencies: varint "^5.0.0" multicodec@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + resolved "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz" integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== dependencies: buffer "^5.6.0" @@ -9624,7 +9350,7 @@ multicodec@^1.0.0: multihashes@^0.4.15, multihashes@~0.4.15: version "0.4.21" - resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + resolved "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz" integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== dependencies: buffer "^5.5.0" @@ -9633,7 +9359,7 @@ multihashes@^0.4.15, multihashes@~0.4.15: multimatch@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" + resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz" integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== dependencies: "@types/minimatch" "^3.0.3" @@ -9644,7 +9370,7 @@ multimatch@^5.0.0: murmur-128@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" + resolved "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz" integrity sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg== dependencies: encode-utf8 "^1.0.2" @@ -9653,27 +9379,27 @@ murmur-128@^0.2.1: mute-stream@0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz" + integrity "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==" mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== nano-json-stream-parser@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + resolved "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz" integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= nanoid@3.3.3: version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanomatch@^1.2.9: version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" @@ -9690,13 +9416,13 @@ nanomatch@^1.2.9: napi-macros@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + resolved "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz" integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" negotiator@0.6.3, negotiator@^0.6.2: version "0.6.3" @@ -9705,7 +9431,7 @@ negotiator@0.6.3, negotiator@^0.6.2: neo-async@^2.6.0: version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== next-tick@^1.1.0: @@ -9715,24 +9441,24 @@ next-tick@^1.1.0: nice-try@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz" 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" + resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== node-emoji@^1.10.0, node-emoji@^1.4.1: version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" + resolved "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz" integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== dependencies: lodash "^4.17.21" node-environment-flags@1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + resolved "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz" integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== dependencies: object.getownpropertydescriptors "^2.0.3" @@ -9740,14 +9466,14 @@ node-environment-flags@1.0.6: node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" node-fetch@~1.7.1: version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz" integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== dependencies: encoding "^0.1.11" @@ -9755,12 +9481,12 @@ node-fetch@~1.7.1: node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz" integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== node-gyp@^5.0.2: version "5.1.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz" integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== dependencies: env-paths "^2.2.0" @@ -9777,7 +9503,7 @@ node-gyp@^5.0.2: node-gyp@^7.1.0: version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz" integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== dependencies: env-paths "^2.2.0" @@ -9798,14 +9524,14 @@ nofilter@^3.1.0: nopt@3.x: version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" + integrity "sha1-xkZdvwirzU2zWTF/eaxopkayj/k= sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==" dependencies: abbrev "1" nopt@^4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz" integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== dependencies: abbrev "1" @@ -9813,14 +9539,14 @@ nopt@^4.0.1: nopt@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== dependencies: abbrev "1" normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, 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" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -9830,7 +9556,7 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package- normalize-package-data@^3.0.0, normalize-package-data@^3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz" integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== dependencies: hosted-git-info "^4.0.1" @@ -9840,7 +9566,7 @@ normalize-package-data@^3.0.0, normalize-package-data@^3.0.2: 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" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-url@^4.1.0: @@ -9850,26 +9576,26 @@ normalize-url@^4.1.0: normalize-url@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-bundled@^1.1.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz" integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" npm-install-checks@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" + resolved "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz" integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== dependencies: semver "^7.1.1" npm-lifecycle@^3.1.5: version "3.1.5" - resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309" + resolved "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz" integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g== dependencies: byline "^5.0.0" @@ -9883,12 +9609,12 @@ npm-lifecycle@^3.1.5: npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5: version "8.1.5" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" + resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz" integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== dependencies: hosted-git-info "^4.0.1" @@ -9897,7 +9623,7 @@ npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-pack npm-packlist@^2.1.4: version "2.2.2" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.2.2.tgz#076b97293fa620f632833186a7a8f65aaa6148c8" + resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz" integrity sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg== dependencies: glob "^7.1.6" @@ -9907,7 +9633,7 @@ npm-packlist@^2.1.4: npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1: version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" + resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz" integrity sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA== dependencies: npm-install-checks "^4.0.0" @@ -9917,7 +9643,7 @@ npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1: npm-registry-fetch@^11.0.0: version "11.0.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz#68c1bb810c46542760d62a6a965f85a702d43a76" + resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz" integrity sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA== dependencies: make-fetch-happen "^9.0.1" @@ -9929,7 +9655,7 @@ npm-registry-fetch@^11.0.0: npm-registry-fetch@^9.0.0: version "9.0.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz#86f3feb4ce00313bc0b8f1f8f69daae6face1661" + resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz" integrity sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA== dependencies: "@npmcli/ci-detect" "^1.0.0" @@ -9943,21 +9669,21 @@ npm-registry-fetch@^9.0.0: npm-run-path@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" + integrity "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==" dependencies: path-key "^2.0.0" npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" npmlog@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" @@ -9967,41 +9693,46 @@ npmlog@^4.1.2: number-is-nan@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + integrity "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" number-to-bn@1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= + resolved "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz" + integrity "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==" dependencies: bn.js "4.11.6" strip-hex-prefix "1.0.0" oauth-sign@~0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== object-assign@^4, object-assign@^4.0.0, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.0, object-inspect@^1.9.0, object-inspect@~1.12.0: +object-inspect@^1.12.0, object-inspect@^1.9.0: version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== +object-inspect@^1.12.2, object-inspect@~1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + object-is@^1.0.1: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -10012,24 +9743,24 @@ object-is@^1.0.1: object-keys@^1.0.11, object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object-keys@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz" integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= object-visit@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.assign@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz" integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== dependencies: define-properties "^1.1.2" @@ -10039,7 +9770,7 @@ object.assign@4.1.0: object.assign@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: call-bind "^1.0.0" @@ -10047,30 +9778,50 @@ object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.1: +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.0.3: version "2.1.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" + resolved "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz" integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" es-abstract "^1.19.1" +object.getownpropertydescriptors@^2.1.1: + version "2.1.5" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" + integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== + dependencies: + array.prototype.reduce "^1.0.5" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + object.pick@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" obliterator@^2.0.0: version "2.0.4" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" + resolved "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz" integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== oboe@2.1.4: version "2.1.4" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" + resolved "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz" integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= dependencies: http-https "^1.0.0" @@ -10084,28 +9835,28 @@ on-finished@2.4.1: once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==" dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz" + integrity "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==" dependencies: mimic-fn "^1.0.0" onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" open@^7.4.2: version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + resolved "https://registry.npmjs.org/open/-/open-7.4.2.tgz" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== dependencies: is-docker "^2.0.0" @@ -10113,7 +9864,7 @@ open@^7.4.2: optionator@^0.8.1, optionator@^0.8.2: version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: deep-is "~0.1.3" @@ -10125,7 +9876,7 @@ optionator@^0.8.1, optionator@^0.8.2: optionator@^0.9.1: version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -10137,29 +9888,29 @@ optionator@^0.9.1: ordinal@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" + resolved "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz" integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== os-homedir@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" + integrity "sha1-/7xJiDNuDoM94MFox+8VISGqf7M= sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==" os-locale@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + resolved "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz" + integrity "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==" dependencies: lcid "^1.0.0" os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + integrity "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" osenv@^0.1.4: version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" @@ -10167,88 +9918,88 @@ osenv@^0.1.4: p-cancelable@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz" integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== p-cancelable@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" + integrity "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" p-limit@^1.1.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-limit@^2.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" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + integrity "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==" dependencies: p-limit "^1.1.0" p-locate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: p-limit "^2.0.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-map-series@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" + resolved "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz" integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== p-map@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-pipe@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" + resolved "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz" integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== p-queue@^6.6.2: version "6.6.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + resolved "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz" integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== dependencies: eventemitter3 "^4.0.4" @@ -10256,43 +10007,43 @@ p-queue@^6.6.2: p-reduce@^2.0.0, p-reduce@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" + resolved "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz" integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== p-timeout@^1.1.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz" integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= dependencies: p-finally "^1.0.0" p-timeout@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== dependencies: p-finally "^1.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 sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + integrity "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= 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" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== p-waterfall@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" + resolved "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz" integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== dependencies: p-reduce "^2.0.0" pacote@^11.2.6: version "11.3.5" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.3.5.tgz#73cf1fc3772b533f575e39efa96c50be8c3dc9d2" + resolved "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz" integrity sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg== dependencies: "@npmcli/git" "^2.1.0" @@ -10317,14 +10068,14 @@ pacote@^11.2.6: parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: asn1.js "^5.2.0" @@ -10335,8 +10086,8 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: parse-cache-control@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" - integrity sha1-juqz5U+laSD+Fro493+iGqzC104= + resolved "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz" + integrity "sha1-juqz5U+laSD+Fro493+iGqzC104= sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" parse-headers@^2.0.0: version "2.0.5" @@ -10345,22 +10096,22 @@ parse-headers@^2.0.0: parse-json@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz" + integrity "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==" dependencies: error-ex "^1.2.0" parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" + integrity "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==" dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" parse-json@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -10370,7 +10121,7 @@ parse-json@^5.0.0: parse-path@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.3.tgz#82d81ec3e071dcc4ab49aa9f2c9c0b8966bb22bf" + resolved "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz" integrity sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA== dependencies: is-ssh "^1.3.0" @@ -10380,7 +10131,7 @@ parse-path@^4.0.0: parse-url@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-6.0.0.tgz#f5dd262a7de9ec00914939220410b66cff09107d" + resolved "https://registry.npmjs.org/parse-url/-/parse-url-6.0.0.tgz" integrity sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw== dependencies: is-ssh "^1.3.0" @@ -10390,17 +10141,17 @@ parse-url@^6.0.0: parseurl@~1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= patch-package@6.2.2: version "6.2.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" + resolved "https://registry.npmjs.org/patch-package/-/patch-package-6.2.2.tgz" integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== dependencies: "@yarnpkg/lockfile" "^1.1.0" @@ -10418,7 +10169,7 @@ patch-package@6.2.2: patch-package@^6.2.2, patch-package@^6.4.7: version "6.4.7" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148" + resolved "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz" integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ== dependencies: "@yarnpkg/lockfile" "^1.1.0" @@ -10437,60 +10188,60 @@ patch-package@^6.2.2, patch-package@^6.4.7: path-browserify@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== path-exists@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" + integrity "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==" dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + integrity "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= 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" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-is-inside@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" + integrity "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" + integrity "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 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" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-to-regexp@0.1.7: version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= path-type@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz" + integrity "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==" dependencies: graceful-fs "^4.1.2" pify "^2.0.0" @@ -10498,24 +10249,24 @@ path-type@^1.0.0: path-type@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pathval@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" @@ -10526,103 +10277,103 @@ pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" + integrity "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pidtree@^0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.5.0.tgz#ad5fbc1de78b8a5f99d6fbdd4f6e4eee21d1aca1" + resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz" integrity sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA== pify@^2.0.0, pify@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + integrity "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" pify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + integrity "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" pify@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pify@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + resolved "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz" integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== pinkie-promise@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + integrity "sha1-ITXW36ejWMBprJsXh3YogihFD/o= sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==" dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + integrity "sha1-clVrgM+g1IqXToDnckjoDtT3+HA= sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" posix-character-classes@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postinstall-postinstall@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" + resolved "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz" integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== precond@0.2: version "0.2.3" - resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" + resolved "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz" integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prelude-ls@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" + integrity "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" prepend-http@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= prepend-http@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= prettier-linter-helpers@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== dependencies: fast-diff "^1.1.2" prettier-plugin-solidity@^1.0.0-beta.6: version "1.0.0-beta.19" - resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz#7c3607fc4028f5e6a425259ff03e45eedf733df3" + resolved "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz" integrity sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g== dependencies: "@solidity-parser/parser" "^0.14.0" @@ -10634,47 +10385,42 @@ prettier-plugin-solidity@^1.0.0-beta.6: prettier@^1.14.3: version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + resolved "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== -prettier@^2.1.2, prettier@^2.3.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== - -prettier@^2.2.1: +prettier@^2.1.2, prettier@^2.2.1, prettier@^2.3.1: version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz" integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== private@^0.1.6, private@^0.1.8: version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + resolved "https://registry.npmjs.org/private/-/private-0.1.8.tgz" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@^0.11.10: version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= progress@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-inflight@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" + integrity "sha1-mEcocL8igTL8vdhoEputEsPAKeM= sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" promise-retry@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== dependencies: err-code "^2.0.2" @@ -10682,7 +10428,7 @@ promise-retry@^2.0.1: promise-to-callback@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" + resolved "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz" integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc= dependencies: is-fn "^1.0.0" @@ -10690,26 +10436,26 @@ promise-to-callback@^1.0.0: promise@^8.0.0, promise@^8.0.2: version "8.1.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" + resolved "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz" integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== dependencies: asap "~2.0.6" promzard@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= + resolved "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz" + integrity "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw==" dependencies: read "1" proto-list@~1.2.1: version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" + integrity "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" protocols@^1.1.0, protocols@^1.4.0: version "1.4.8" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" + resolved "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz" integrity sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg== proxy-addr@~2.0.7: @@ -10722,22 +10468,22 @@ proxy-addr@~2.0.7: prr@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= pseudomap@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.28: version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== public-encrypt@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" @@ -10749,17 +10495,17 @@ public-encrypt@^4.0.0: pull-cat@^1.1.9: version "1.1.11" - resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" + resolved "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz" integrity sha1-tkLdElXaN2pwa220+pYvX9t0wxs= pull-defer@^0.2.2: version "0.2.3" - resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" + resolved "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz" integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== pull-level@^2.0.3: version "2.0.4" - resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" + resolved "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz" integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== dependencies: level-post "^1.0.7" @@ -10772,7 +10518,7 @@ pull-level@^2.0.3: pull-live@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" + resolved "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz" integrity sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU= dependencies: pull-cat "^1.1.9" @@ -10780,24 +10526,24 @@ pull-live@^1.0.1: pull-pushable@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" + resolved "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz" integrity sha1-Xy867UethpGfAbEqLpnW8b13ZYE= pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: version "3.6.14" - resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" + resolved "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz" integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew== pull-window@^2.1.4: version "2.1.4" - resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" + resolved "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz" integrity sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA= dependencies: looper "^2.0.0" pump@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -10805,27 +10551,34 @@ pump@^3.0.0: punycode@1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" + integrity "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" -punycode@2.1.0: +punycode@2.1.0, punycode@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz" + integrity "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==" -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== q@^1.5.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz" + integrity "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" -qs@6.10.3, qs@^6.4.0, qs@^6.7.0, qs@^6.9.4: +qs@^6.4.0, qs@^6.7.0, qs@^6.9.4: version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + resolved "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz" integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== dependencies: side-channel "^1.0.4" @@ -10837,7 +10590,7 @@ qs@~6.5.2: query-string@^5.0.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + resolved "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz" integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== dependencies: decode-uri-component "^0.2.0" @@ -10846,7 +10599,7 @@ query-string@^5.0.1: query-string@^6.13.8: version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" + resolved "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz" integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== dependencies: decode-uri-component "^0.2.0" @@ -10856,29 +10609,29 @@ query-string@^6.13.8: querystring@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" + integrity "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-lru@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" + resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz" integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" @@ -10886,7 +10639,7 @@ randomfill@^1.0.3: range-parser@~1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== raw-body@2.5.1, raw-body@^2.4.1: @@ -10899,14 +10652,24 @@ raw-body@2.5.1, raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@2.5.2: + 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-cmd-shim@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz#4a50a71d6f0965364938e9038476f7eede3928d9" + resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz" integrity sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw== read-package-json-fast@^2.0.1: version "2.0.3" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" + resolved "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz" integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== dependencies: json-parse-even-better-errors "^2.3.0" @@ -10914,7 +10677,7 @@ read-package-json-fast@^2.0.1: read-package-json@^2.0.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" + resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz" integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== dependencies: glob "^7.1.1" @@ -10924,7 +10687,7 @@ read-package-json@^2.0.0: read-package-json@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-3.0.1.tgz#c7108f0b9390257b08c21e3004d2404c806744b9" + resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-3.0.1.tgz" integrity sha512-aLcPqxovhJTVJcsnROuuzQvv6oziQx4zd3JvG0vGCL5MjTONUc4uJ90zCBC6R7W7oUKBNoR/F8pkyfVwlbxqng== dependencies: glob "^7.1.1" @@ -10934,7 +10697,7 @@ read-package-json@^3.0.0: read-package-json@^4.1.1: version "4.1.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-4.1.2.tgz#b444d047de7c75d4a160cb056d00c0693c1df703" + resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-4.1.2.tgz" integrity sha512-Dqer4pqzamDE2O4M55xp1qZMuLPqi4ldk2ya648FOMHRjwMzFhuxVrG04wd0c38IsvkVdr3vgHI6z+QTPdAjrQ== dependencies: glob "^7.1.1" @@ -10944,7 +10707,7 @@ read-package-json@^4.1.1: read-package-tree@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636" + resolved "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz" integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw== dependencies: read-package-json "^2.0.0" @@ -10953,23 +10716,23 @@ read-package-tree@^5.3.1: read-pkg-up@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz" + integrity "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==" dependencies: find-up "^1.0.0" read-pkg "^1.0.0" read-pkg-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz" + integrity "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==" dependencies: find-up "^2.0.0" read-pkg "^3.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" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz" integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== dependencies: find-up "^4.1.0" @@ -10978,8 +10741,8 @@ read-pkg-up@^7.0.1: read-pkg@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz" + integrity "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==" dependencies: load-json-file "^1.0.0" normalize-package-data "^2.3.2" @@ -10987,8 +10750,8 @@ read-pkg@^1.0.0: read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" + integrity "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==" dependencies: load-json-file "^4.0.0" normalize-package-data "^2.3.2" @@ -10996,7 +10759,7 @@ read-pkg@^3.0.0: read-pkg@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz" integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== dependencies: "@types/normalize-package-data" "^2.4.0" @@ -11006,14 +10769,14 @@ read-pkg@^5.2.0: read@1, read@~1.0.1: version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz" + integrity "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==" dependencies: mute-stream "~0.0.4" readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" @@ -11022,7 +10785,7 @@ readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stre readable-stream@^1.0.33: version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz" integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= dependencies: core-util-is "~1.0.0" @@ -11032,7 +10795,7 @@ readable-stream@^1.0.33: readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -11045,7 +10808,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6, readable readable-stream@~1.0.15: version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= dependencies: core-util-is "~1.0.0" @@ -11055,7 +10818,7 @@ readable-stream@~1.0.15: readdir-scoped-modules@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" + resolved "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== dependencies: debuglog "^1.0.1" @@ -11065,35 +10828,35 @@ readdir-scoped-modules@^1.0.0: readdirp@~3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz" integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== dependencies: picomatch "^2.0.4" readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" rechoir@^0.6.2: version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" + integrity "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==" dependencies: resolve "^1.1.6" recursive-readdir@^2.2.2: version "2.2.2" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + resolved "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz" integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== dependencies: minimatch "3.0.4" redent@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== dependencies: indent-string "^4.0.0" @@ -11101,29 +10864,29 @@ redent@^3.0.0: redeyed@~2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b" - integrity sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs= + resolved "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz" + integrity "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs= sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==" dependencies: esprima "~4.0.0" reduce-flatten@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + resolved "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== regenerate@^1.2.1: version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.11.0: version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-transform@^0.10.0: version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz" integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== dependencies: babel-runtime "^6.18.0" @@ -11132,15 +10895,15 @@ regenerator-transform@^0.10.0: regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1: +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: call-bind "^1.0.2" @@ -11149,17 +10912,17 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1: regexpp@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpp@^3.1.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== regexpu-core@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz" integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= dependencies: regenerate "^1.2.1" @@ -11168,12 +10931,12 @@ regexpu-core@^2.0.0: regjsgen@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz" integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= regjsparser@^0.1.4: version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz" integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= dependencies: jsesc "~0.5.0" @@ -11185,40 +10948,40 @@ repeat-element@^1.1.2: repeat-string@^1.6.1: version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= repeating@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz" integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= dependencies: is-finite "^1.0.0" req-cwd@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" - integrity sha1-1AgrTURZgDZkD7c93qAe1T20nrw= + resolved "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz" + integrity "sha1-1AgrTURZgDZkD7c93qAe1T20nrw= sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==" dependencies: req-from "^2.0.0" req-from@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/req-from/-/req-from-2.0.0.tgz#d74188e47f93796f4aa71df6ee35ae689f3e0e70" - integrity sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA= + resolved "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz" + integrity "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA= sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==" dependencies: resolve-from "^3.0.0" request-promise-core@1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz" integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== dependencies: lodash "^4.17.19" request-promise-native@^1.0.5: version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + resolved "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz" integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== dependencies: request-promise-core "1.1.4" @@ -11227,7 +10990,7 @@ request-promise-native@^1.0.5: request-promise@^4.2.2: version "4.2.6" - resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.6.tgz#7e7e5b9578630e6f598e3813c0f8eb342a27f0a2" + resolved "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz" integrity sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ== dependencies: bluebird "^3.5.0" @@ -11237,7 +11000,7 @@ request-promise@^4.2.2: request@^2.79.0, request@^2.85.0, request@^2.88.0, request@^2.88.2: version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" @@ -11263,95 +11026,95 @@ request@^2.79.0, request@^2.85.0, request@^2.88.0, request@^2.88.2: require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity "sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" require-from-string@^1.1.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz" + integrity "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==" require-from-string@^2.0.0, require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== require-main-filename@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz" + integrity "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" require-main-filename@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: resolve-from "^5.0.0" resolve-from@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz" + integrity "sha1-six699nWiBvItuZTM17rywoYh0g= sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-url@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@1.1.x: version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + resolved "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz" + integrity "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==" -resolve@1.17.0: +resolve@1.17.0, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.8.1: version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz" integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.8.1, resolve@~1.22.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== +resolve@~1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== dependencies: - is-core-module "^2.8.1" + is-core-module "^2.9.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" responselike@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= dependencies: lowercase-keys "^1.0.0" restore-cursor@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz" + integrity "sha1-n37ih/gv0ybU/RYpI9YhKe7g368= sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==" dependencies: onetime "^2.0.0" signal-exit "^3.0.2" restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -11359,55 +11122,55 @@ restore-cursor@^3.1.0: resumer@~0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + resolved "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz" integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= dependencies: through "~2.3.4" ret@~0.1.10: version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== retry@^0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + integrity "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rfdc@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== rimraf@2.6.3: version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" rimraf@^2.2.8, rimraf@^2.6.3: version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 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" + resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" @@ -11415,88 +11178,90 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4: version "2.2.7" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + resolved "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz" integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== dependencies: bn.js "^5.2.0" run-async@^2.2.0, run-async@^2.4.0: version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" 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" + resolved "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz" 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" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 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" + resolved "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== rxjs@^6.4.0, rxjs@^6.6.0: version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" -rxjs@^7.0.0: - version "7.5.6" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" - integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== - dependencies: - tslib "^2.1.0" - -rxjs@^7.2.0, rxjs@^7.5.5: +rxjs@^7.0.0, rxjs@^7.2.0, rxjs@^7.5.5: version "7.5.5" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz" integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== dependencies: tslib "^2.1.0" safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-event-emitter@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" + resolved "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz" integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== dependencies: events "^3.0.0" +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + safe-regex@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sc-istanbul@^0.4.5: version "0.4.6" - resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" + resolved "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz" integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g== dependencies: abbrev "1.0.x" @@ -11516,24 +11281,24 @@ sc-istanbul@^0.4.5: scrypt-js@2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" + resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== scryptsy@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + resolved "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz" integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= dependencies: pbkdf2 "^3.0.3" secp256k1@^4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" + resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== dependencies: elliptic "^6.5.4" @@ -11542,34 +11307,34 @@ secp256k1@^4.0.1: seedrandom@3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" + resolved "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.1.tgz" integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg== semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" + resolved "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz" integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^6.0.0, semver@^6.3.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" semver@~5.4.1: version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + resolved "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz" integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== send@0.18.0: @@ -11593,7 +11358,7 @@ send@0.18.0: serialize-javascript@6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== dependencies: randombytes "^2.1.0" @@ -11610,7 +11375,7 @@ serve-static@1.15.0: servify@^0.1.12: version "0.1.12" - resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + resolved "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz" integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== dependencies: body-parser "^1.16.0" @@ -11621,17 +11386,17 @@ servify@^0.1.12: set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity "sha1-BF+XgtARrppoA93TgrJDkrPYkPc= sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" set-immediate-shim@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + resolved "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz" integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: extend-shallow "^2.0.1" @@ -11641,22 +11406,22 @@ set-value@^2.0.0, set-value@^2.0.1: setimmediate@1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz" + integrity "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==" setimmediate@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + integrity "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= 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" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" 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" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -11664,51 +11429,51 @@ sha.js@^2.4.0, sha.js@^2.4.8: sha1@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" - integrity sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg= + resolved "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz" + integrity "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg= sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==" dependencies: charenc ">= 0.0.1" crypt ">= 0.0.1" shallow-clone@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== dependencies: kind-of "^6.0.2" shebang-command@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + integrity "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==" dependencies: shebang-regex "^1.0.0" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + integrity "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.7.3: version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz" integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== shelljs@^0.8.3: version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== dependencies: glob "^7.0.0" @@ -11717,7 +11482,7 @@ shelljs@^0.8.3: side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -11726,12 +11491,12 @@ side-channel@^1.0.4: signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simple-concat@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== simple-get@^2.7.0: @@ -11745,22 +11510,22 @@ simple-get@^2.7.0: slash@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= slash@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz" integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: ansi-styles "^3.2.0" @@ -11769,7 +11534,7 @@ slice-ansi@^2.1.0: slice-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: ansi-styles "^4.0.0" @@ -11778,7 +11543,7 @@ slice-ansi@^3.0.0: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -11787,7 +11552,7 @@ slice-ansi@^4.0.0: slice-ansi@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz" integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== dependencies: ansi-styles "^6.0.0" @@ -11795,17 +11560,17 @@ slice-ansi@^5.0.0: slide@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + resolved "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" + integrity "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==" smart-buffer@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== snapdragon-node@^2.0.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" @@ -11814,14 +11579,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" @@ -11835,7 +11600,7 @@ snapdragon@^0.8.1: socks-proxy-agent@^5.0.0: version "5.0.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz" integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== dependencies: agent-base "^6.0.2" @@ -11844,7 +11609,7 @@ socks-proxy-agent@^5.0.0: socks-proxy-agent@^6.0.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz#f6b5229cc0cbd6f2f202d9695f09d871e951c85e" + resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz" integrity sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ== dependencies: agent-base "^6.0.2" @@ -11853,7 +11618,7 @@ socks-proxy-agent@^6.0.0: socks@^2.3.3, socks@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" + resolved "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz" integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== dependencies: ip "^1.1.5" @@ -11861,7 +11626,7 @@ socks@^2.3.3, socks@^2.6.2: solc@0.7.3: version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" + resolved "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz" integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== dependencies: command-exists "^1.2.8" @@ -11876,7 +11641,7 @@ solc@0.7.3: solc@^0.4.20: version "0.4.26" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + resolved "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz" integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== dependencies: fs-extra "^0.30.0" @@ -11887,7 +11652,7 @@ solc@^0.4.20: solc@^0.6.3: version "0.6.12" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.6.12.tgz#48ac854e0c729361b22a7483645077f58cba080e" + resolved "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz" integrity sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g== dependencies: command-exists "^1.2.8" @@ -11901,14 +11666,14 @@ solc@^0.6.3: solhint-plugin-prettier@^0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz#e3b22800ba435cd640a9eca805a7f8bc3e3e6a6b" + resolved "https://registry.npmjs.org/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz" integrity sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA== dependencies: prettier-linter-helpers "^1.0.0" solhint@^3.3.6: version "3.3.7" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.7.tgz#b5da4fedf7a0fee954cb613b6c55a5a2b0063aa7" + resolved "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz" integrity sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ== dependencies: "@solidity-parser/parser" "^0.14.1" @@ -11930,12 +11695,12 @@ solhint@^3.3.6: solidity-comments-extractor@^0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + resolved "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz" integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== solidity-coverage@^0.8.2: version "0.8.2" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.2.tgz#bc39604ab7ce0a3fa7767b126b44191830c07813" + resolved "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz" integrity sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ== dependencies: "@ethersproject/abi" "^5.0.9" @@ -11961,21 +11726,21 @@ solidity-coverage@^0.8.2: sort-keys@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz" + integrity "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==" dependencies: is-plain-obj "^1.0.0" sort-keys@^4.0.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18" + resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz" integrity sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg== dependencies: is-plain-obj "^2.0.0" source-map-resolve@^0.5.0: version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: atob "^2.1.2" @@ -11986,7 +11751,7 @@ source-map-resolve@^0.5.0: source-map-support@0.5.12: version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz" integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== dependencies: buffer-from "^1.0.0" @@ -11994,14 +11759,14 @@ source-map-support@0.5.12: source-map-support@^0.4.15: version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz" integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== dependencies: source-map "^0.5.6" source-map-support@^0.5.13, source-map-support@^0.5.17: version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -12014,29 +11779,29 @@ source-map-url@^0.4.0: source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@~0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + resolved "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz" + integrity "sha1-2rc/vPwrqBm03gO9b26qSBZLP50= sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==" dependencies: amdefine ">=0.0.4" spawn-command@^0.0.2-1: version "0.0.2-1" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + resolved "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz" integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== spdx-correct@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" @@ -12044,12 +11809,12 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" @@ -12057,43 +11822,43 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz" integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== split-on-first@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" split2@^3.0.0: version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" + resolved "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz" integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== dependencies: readable-stream "^3.0.0" split@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + resolved "https://registry.npmjs.org/split/-/split-1.0.1.tgz" integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== dependencies: through "2" sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" sshpk@^1.7.0: version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== dependencies: asn1 "~0.2.3" @@ -12108,21 +11873,21 @@ sshpk@^1.7.0: ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: minipass "^3.1.1" stacktrace-parser@^0.1.10: version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz" integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== dependencies: type-fest "^0.7.1" static-extend@^0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" @@ -12130,17 +11895,17 @@ static-extend@^0.1.1: statuses@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== stealthy-require@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz" + integrity "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==" stream-to-pull-stream@^1.7.1: version "1.7.3" - resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" + resolved "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz" integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== dependencies: looper "^3.0.0" @@ -12153,28 +11918,28 @@ streamsearch@^1.1.0: strict-uri-encode@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= strict-uri-encode@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz" + integrity "sha1-ucczDHBChi9rFC3CdLvMWGbONUY= sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==" string-argv@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== string-format@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + resolved "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz" integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== string-width@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + integrity "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==" dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -12182,7 +11947,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" @@ -12190,7 +11955,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -12199,7 +11964,7 @@ string-width@^1.0.1: string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== dependencies: emoji-regex "^7.0.1" @@ -12208,148 +11973,166 @@ string-width@^3.0.0, string-width@^3.1.0: string-width@^5.0.0: version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: eastasianwidth "^0.2.0" emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string.prototype.trim@~1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.6.tgz#824960787db37a9e24711802ed0c1d1c0254f83e" - integrity sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ== +string.prototype.trim@~1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" - es-abstract "^1.19.5" + es-abstract "^1.20.4" string.prototype.trimend@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz" integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" es-abstract "^1.19.5" +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string.prototype.trimstart@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz" integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" es-abstract "^1.19.5" +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~0.10.x: version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + integrity "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==" dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + integrity "sha1-qEeQIusaw2iocTibY1JixQXuNo8= sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==" dependencies: ansi-regex "^3.0.0" strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-ansi@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz" integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== dependencies: ansi-regex "^6.0.1" strip-bom@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" + integrity "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==" dependencies: is-utf8 "^0.2.0" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-eof@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" + integrity "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==" strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 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 sha1-DF8VX+8RUTczd96du1iNoFUA428= + resolved "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz" + integrity "sha1-DF8VX+8RUTczd96du1iNoFUA428= 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" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== dependencies: min-indent "^1.0.0" strip-json-comments@2.0.1, 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 sha1-PFMZQukIwml8DsNEhYwobHygpgo= + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + integrity "sha1-PFMZQukIwml8DsNEhYwobHygpgo= sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" strip-json-comments@3.1.1, strip-json-comments@^3.1.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" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strong-log-transformer@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" + resolved "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz" integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== dependencies: duplexer "^0.1.1" @@ -12358,52 +12141,52 @@ strong-log-transformer@^2.1.0: supports-color@6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz" integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== dependencies: has-flag "^3.0.0" supports-color@8.1.1, supports-color@^8.1.0: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" supports-color@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^3.1.0: version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + resolved "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz" + integrity "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==" dependencies: has-flag "^1.0.0" supports-color@^5.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" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^9.2.1: version "9.2.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.2.tgz#502acaf82f2b7ee78eb7c83dcac0f89694e5a7bb" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz" integrity sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA== supports-hyperlinks@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" + resolved "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz" integrity sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw== dependencies: has-flag "^2.0.0" @@ -12416,7 +12199,7 @@ supports-preserve-symlinks-flag@^1.0.0: swarm-js@^0.1.40: version "0.1.40" - resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99" + resolved "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz" integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA== dependencies: bluebird "^3.5.0" @@ -12433,7 +12216,7 @@ swarm-js@^0.1.40: sync-request@^6.0.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" + resolved "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz" integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw== dependencies: http-response-object "^3.0.1" @@ -12442,14 +12225,14 @@ sync-request@^6.0.0: sync-rpc@^1.2.1: version "1.3.6" - resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7" + resolved "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz" integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw== dependencies: get-port "^3.1.0" table-layout@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + resolved "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz" integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== dependencies: array-back "^4.0.1" @@ -12459,7 +12242,7 @@ table-layout@^1.0.2: table@^5.2.3: version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + resolved "https://registry.npmjs.org/table/-/table-5.4.6.tgz" integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== dependencies: ajv "^6.10.2" @@ -12469,7 +12252,7 @@ table@^5.2.3: table@^6.0.9: version "6.8.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" + resolved "https://registry.npmjs.org/table/-/table-6.8.0.tgz" integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== dependencies: ajv "^8.0.1" @@ -12490,24 +12273,24 @@ table@^6.8.0: strip-ansi "^6.0.1" tape@^4.6.3: - version "4.15.1" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.15.1.tgz#88fb662965a11f9be1bddb04c11662d7eceb129e" - integrity sha512-k7F5pyr91n9D/yjSJwbLLYDCrTWXxMSXbbmHX2n334lSIc2rxeXyFkaBv4UuUd2gBYMrAOalPutAiCxC6q1qbw== + version "4.16.2" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.16.2.tgz#7565e6af20426565557266e9dda7215869b297b6" + integrity sha512-TUChV+q0GxBBCEbfCYkGLkv8hDJYjMdSWdE0/Lr331sB389dsvFUHNV9ph5iQqKzt8Ss9drzcda/YeexclBFqg== dependencies: call-bind "~1.0.2" deep-equal "~1.1.1" - defined "~1.0.0" + defined "~1.0.1" dotignore "~0.1.2" for-each "~0.3.3" - glob "~7.2.0" + glob "~7.2.3" has "~1.0.3" inherits "~2.0.4" is-regex "~1.1.4" - minimist "~1.2.6" - object-inspect "~1.12.0" - resolve "~1.22.0" + minimist "~1.2.7" + object-inspect "~1.12.3" + resolve "~1.22.1" resumer "~0.0.0" - string.prototype.trim "~1.2.5" + string.prototype.trim "~1.2.7" through "~2.3.8" tar@^4.0.2, tar@^4.4.12: @@ -12525,7 +12308,7 @@ tar@^4.0.2, tar@^4.4.12: tar@^6.0.2, tar@^6.1.0: version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + resolved "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== dependencies: chownr "^2.0.0" @@ -12537,12 +12320,12 @@ tar@^6.0.2, tar@^6.1.0: temp-dir@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz" + integrity "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==" temp-write@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-4.0.0.tgz#cd2e0825fc826ae72d201dc26eef3bf7e6fc9320" + resolved "https://registry.npmjs.org/temp-write/-/temp-write-4.0.0.tgz" integrity sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw== dependencies: graceful-fs "^4.1.15" @@ -12553,7 +12336,7 @@ temp-write@^4.0.0: test-value@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" + resolved "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz" integrity sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w== dependencies: array-back "^1.0.3" @@ -12561,22 +12344,22 @@ test-value@^2.1.0: testrpc@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + resolved "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz" integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== text-extensions@^1.0.0: version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + resolved "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" then-request@^6.0.0: version "6.0.2" - resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" + resolved "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz" integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA== dependencies: "@types/concat-stream" "^1.6.0" @@ -12593,7 +12376,7 @@ then-request@^6.0.0: through2@^2.0.0, through2@^2.0.3: version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== dependencies: readable-stream "~2.3.6" @@ -12601,55 +12384,55 @@ through2@^2.0.0, through2@^2.0.3: through2@^4.0.0: version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" + resolved "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz" integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== dependencies: readable-stream "3" through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8, through@~2.3.4, through@~2.3.8: version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz" integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= tmp@0.0.33, tmp@^0.0.33: version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" tmp@0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz" integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== dependencies: rimraf "^2.6.3" to-fast-properties@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz" integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= to-object-path@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-readable-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== to-regex-range@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" @@ -12657,14 +12440,14 @@ to-regex-range@^2.1.0: to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" @@ -12674,12 +12457,12 @@ to-regex@^3.0.1, to-regex@^3.0.2: toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== dependencies: psl "^1.1.28" @@ -12687,34 +12470,34 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: tr46@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + resolved "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz" integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" tr46@~0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + integrity "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" tree-kill@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== trim-newlines@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== trim-right@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= ts-command-line-args@^2.2.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz#b6188e42efc6cf7a8898e438a873fbb15505ddd6" + resolved "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.3.1.tgz" integrity sha512-FR3y7pLl/fuUNSmnPhfLArGqRrpojQgIEEOVzYx9DhTmfIN7C9RWSfpkJEF4J+Gk7aVx5pak8I7vWZsaN4N84g== dependencies: chalk "^4.1.0" @@ -12724,22 +12507,22 @@ ts-command-line-args@^2.2.0: ts-essentials@^1.0.0, ts-essentials@^1.0.2: version "1.0.4" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-1.0.4.tgz#ce3b5dade5f5d97cf69889c11bf7d2da8555b15a" + resolved "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz" integrity sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ== ts-essentials@^6.0.3: version "6.0.7" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-6.0.7.tgz#5f4880911b7581a873783740ce8b94da163d18a6" + resolved "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz" integrity sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw== ts-essentials@^7.0.1: version "7.0.3" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" + resolved "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz" integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== ts-generator@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/ts-generator/-/ts-generator-0.1.1.tgz#af46f2fb88a6db1f9785977e9590e7bcd79220ab" + resolved "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz" integrity sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ== dependencies: "@types/mkdirp" "^0.5.2" @@ -12754,7 +12537,7 @@ ts-generator@^0.1.1: ts-node@^8.0.2: version "8.10.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz" integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA== dependencies: arg "^4.1.0" @@ -12765,7 +12548,7 @@ ts-node@^8.0.2: ts-node@^9.0.0: version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz" integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== dependencies: arg "^4.1.0" @@ -12777,105 +12560,105 @@ ts-node@^9.0.0: tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.1.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tsort@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= + resolved "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz" + integrity "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y= sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" tunnel-agent@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + integrity "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==" dependencies: safe-buffer "^5.0.1" tweetnacl-util@^0.15.0, tweetnacl-util@^0.15.1: version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + resolved "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" + integrity "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" tweetnacl@^1.0.0, tweetnacl@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-check@~0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" + integrity "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==" dependencies: prelude-ls "~1.1.2" type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.18.0: version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz" integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== type-fest@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" 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" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz" 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" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== type-is@~1.6.18: version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" @@ -12883,17 +12666,17 @@ type-is@~1.6.18: type@^1.0.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + resolved "https://registry.npmjs.org/type/-/type-1.2.0.tgz" integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== -type@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" - integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== typechain@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-3.0.0.tgz#d5a47700831f238e43f7429b987b4bb54849b92e" + resolved "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz" integrity sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg== dependencies: command-line-args "^4.0.7" @@ -12906,7 +12689,7 @@ typechain@^3.0.0: typechain@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.0.tgz#fc4902ce596519cb2ccfd012e4ddf92a9945b569" + resolved "https://registry.npmjs.org/typechain/-/typechain-8.1.0.tgz" integrity sha512-5jToLgKTjHdI1VKqs/K8BLYy42Sr3o8bV5ojh4MnR9ExHO83cyyUdw+7+vMJCpKXUiVUvARM4qmHTFuyaCMAZQ== dependencies: "@types/prettier" "^2.1.1" @@ -12920,78 +12703,87 @@ typechain@^8.1.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + typedarray-to-buffer@^3.1.5: version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" typedarray@^0.0.6: version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + integrity "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" typescript@^4.3.2: version "4.6.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz" integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== typewise-core@^1.2, typewise-core@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" + resolved "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz" integrity sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU= typewise@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" + resolved "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz" integrity sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE= dependencies: typewise-core "^1.2.0" typewiselite@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" + resolved "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz" integrity sha1-yIgvobsQksBgBal/NO9chQjjZk4= typical@^2.6.0, typical@^2.6.1: version "2.6.1" - resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" + resolved "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz" integrity sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg== typical@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + resolved "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz" integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== typical@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + resolved "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz" integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== uglify-js@^3.1.4: version "3.15.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.5.tgz#2b10f9e0bfb3f5c15a8e8404393b6361eaeb33b3" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz" integrity sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ== uid-number@0.0.6: version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= + resolved "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz" + integrity "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= sha512-c461FXIljswCuscZn67xq9PpszkPT6RjheWFQTgCyabJrTUozElanb0YEqv2UGgk247YpcJkFBuSGNvBlpXM9w==" ultron@~1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + resolved "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz" integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== umask@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" - integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= + resolved "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz" + integrity "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= sha512-lE/rxOhmiScJu9L6RTNVgB/zZbF+vGC0/p6D3xnkAePI2o0sMyFG966iR5Ki50OI/0mNi2yaRnxfLsPmEZF/JA==" unbox-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: call-bind "^1.0.2" @@ -13001,7 +12793,7 @@ unbox-primitive@^1.0.2: underscore@1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz" integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== undici@^5.14.0: @@ -13013,12 +12805,12 @@ undici@^5.14.0: undici@^5.4.0: version "5.8.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.8.0.tgz#dec9a8ccd90e5a1d81d43c0eab6503146d649a4f" + resolved "https://registry.npmjs.org/undici/-/undici-5.8.0.tgz" integrity sha512-1F7Vtcez5w/LwH2G2tGnFIihuWUlc58YidwLiCv+jR2Z50x0tNXpRRw7eOIJ+GvqCqIkg9SB7NWAJ/T9TLfv8Q== union-value@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== dependencies: arr-union "^3.1.0" @@ -13028,46 +12820,46 @@ union-value@^1.0.0: unique-filename@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz" integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== dependencies: unique-slug "^2.0.0" unique-slug@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz" integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== dependencies: imurmurhash "^0.1.4" universal-user-agent@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" + resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== universalify@^0.1.0: version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" 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" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== unorm@^1.3.3: version "1.6.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + resolved "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz" integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" unset-value@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" @@ -13075,90 +12867,90 @@ unset-value@^1.0.0: upath@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" + resolved "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-join@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + resolved "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== url-parse-lax@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz" integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" url-parse-lax@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= dependencies: prepend-http "^2.0.0" url-set-query@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + resolved "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz" integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= url-to-options@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + resolved "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz" integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= url@^0.11.0: version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz" + integrity "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==" dependencies: punycode "1.3.2" querystring "0.2.0" use@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== utf-8-validate@^5.0.2: - version "5.0.9" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3" - integrity sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q== + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== dependencies: node-gyp-build "^4.3.0" utf8@3.0.0, utf8@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" util-promisify@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53" - integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM= + resolved "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz" + integrity "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM= sha512-K+5eQPYs14b3+E+hmE2J6gCZ4JmMl9DbYS6BeP2CHq6WMuNxErxf5B/n0fz85L8zUuoO6rIzNNmIQDu/j+1OcA==" dependencies: object.getownpropertydescriptors "^2.0.3" util.promisify@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + resolved "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz" integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== dependencies: call-bind "^1.0.0" @@ -13169,37 +12961,37 @@ util.promisify@^1.0.0: utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= + resolved "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" + integrity "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==" uuid@3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== uuid@^3.3.2: version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== uuid@^8.3.2: version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-compile-cache@^2.0.3: version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -13207,25 +12999,25 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: validate-npm-package-name@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz" + integrity "sha1-X6kS2B630MdK/BQN5zF/DKffQ34= sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==" dependencies: builtins "^1.0.3" varint@^5.0.0: version "5.0.2" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + resolved "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz" integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== vary@^1, vary@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= verror@1.10.0: version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" + integrity "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==" dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -13233,14 +13025,14 @@ verror@1.10.0: wcwidth@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" + integrity "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==" dependencies: defaults "^1.0.3" web3-bzz@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" + resolved "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.11.tgz" integrity sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg== dependencies: "@types/node" "^12.12.6" @@ -13250,7 +13042,7 @@ web3-bzz@1.2.11: web3-core-helpers@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99" + resolved "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz" integrity sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A== dependencies: underscore "1.9.1" @@ -13259,7 +13051,7 @@ web3-core-helpers@1.2.11: web3-core-method@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6" + resolved "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.11.tgz" integrity sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw== dependencies: "@ethersproject/transactions" "^5.0.0-beta.135" @@ -13271,14 +13063,14 @@ web3-core-method@1.2.11: web3-core-promievent@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf" + resolved "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz" integrity sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA== dependencies: eventemitter3 "4.0.4" web3-core-requestmanager@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a" + resolved "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz" integrity sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA== dependencies: underscore "1.9.1" @@ -13289,7 +13081,7 @@ web3-core-requestmanager@1.2.11: web3-core-subscriptions@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd" + resolved "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz" integrity sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg== dependencies: eventemitter3 "4.0.4" @@ -13298,7 +13090,7 @@ web3-core-subscriptions@1.2.11: web3-core@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7" + resolved "https://registry.npmjs.org/web3-core/-/web3-core-1.2.11.tgz" integrity sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ== dependencies: "@types/bn.js" "^4.11.5" @@ -13311,7 +13103,7 @@ web3-core@1.2.11: web3-eth-abi@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0" + resolved "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz" integrity sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg== dependencies: "@ethersproject/abi" "5.0.0-beta.153" @@ -13320,7 +13112,7 @@ web3-eth-abi@1.2.11: web3-eth-accounts@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520" + resolved "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz" integrity sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw== dependencies: crypto-browserify "3.12.0" @@ -13337,7 +13129,7 @@ web3-eth-accounts@1.2.11: web3-eth-contract@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90" + resolved "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz" integrity sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow== dependencies: "@types/bn.js" "^4.11.5" @@ -13352,7 +13144,7 @@ web3-eth-contract@1.2.11: web3-eth-ens@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532" + resolved "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz" integrity sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA== dependencies: content-hash "^2.5.2" @@ -13367,7 +13159,7 @@ web3-eth-ens@1.2.11: web3-eth-iban@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef" + resolved "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz" integrity sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ== dependencies: bn.js "^4.11.9" @@ -13375,7 +13167,7 @@ web3-eth-iban@1.2.11: web3-eth-personal@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70" + resolved "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz" integrity sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw== dependencies: "@types/node" "^12.12.6" @@ -13387,7 +13179,7 @@ web3-eth-personal@1.2.11: web3-eth@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793" + resolved "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.11.tgz" integrity sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ== dependencies: underscore "1.9.1" @@ -13406,7 +13198,7 @@ web3-eth@1.2.11: web3-net@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b" + resolved "https://registry.npmjs.org/web3-net/-/web3-net-1.2.11.tgz" integrity sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg== dependencies: web3-core "1.2.11" @@ -13415,7 +13207,7 @@ web3-net@1.2.11: web3-provider-engine@14.2.1: version "14.2.1" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz#ef351578797bf170e08d529cb5b02f8751329b95" + resolved "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.2.1.tgz" integrity sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw== dependencies: async "^2.5.0" @@ -13441,7 +13233,7 @@ web3-provider-engine@14.2.1: web3-providers-http@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6" + resolved "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.11.tgz" integrity sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA== dependencies: web3-core-helpers "1.2.11" @@ -13449,7 +13241,7 @@ web3-providers-http@1.2.11: web3-providers-ipc@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21" + resolved "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz" integrity sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ== dependencies: oboe "2.1.4" @@ -13458,7 +13250,7 @@ web3-providers-ipc@1.2.11: web3-providers-ws@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb" + resolved "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz" integrity sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg== dependencies: eventemitter3 "4.0.4" @@ -13468,7 +13260,7 @@ web3-providers-ws@1.2.11: web3-shh@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f" + resolved "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.11.tgz" integrity sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg== dependencies: web3-core "1.2.11" @@ -13478,7 +13270,7 @@ web3-shh@1.2.11: web3-utils@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82" + resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.11.tgz" integrity sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ== dependencies: bn.js "^4.11.9" @@ -13490,9 +13282,9 @@ web3-utils@1.2.11: underscore "1.9.1" utf8 "3.0.0" -web3-utils@^1.0.0-beta.31: +web3-utils@^1.0.0-beta.31, web3-utils@^1.3.6: version "1.7.3" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.7.3.tgz#b214d05f124530d8694ad364509ac454d05f207c" + resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.3.tgz" integrity sha512-g6nQgvb/bUpVUIxJE+ezVN+rYwYmlFyMvMIRSuqpi1dk6ApDD00YNArrk7sPcZnjvxOJ76813Xs2vIN2rgh4lg== dependencies: bn.js "^4.11.9" @@ -13503,22 +13295,9 @@ web3-utils@^1.0.0-beta.31: randombytes "^2.1.0" utf8 "3.0.0" -web3-utils@^1.3.6: - version "1.8.1" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.1.tgz#f2f7ca7eb65e6feb9f3d61056d0de6bbd57125ff" - integrity sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ== - dependencies: - bn.js "^5.2.1" - ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - web3@1.2.11: version "1.2.11" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" + resolved "https://registry.npmjs.org/web3/-/web3-1.2.11.tgz" integrity sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ== dependencies: web3-bzz "1.2.11" @@ -13536,17 +13315,17 @@ webextension-polyfill@^0.10.0: webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + integrity "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" webidl-conversions@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== -websocket@1.0.32: +websocket@1.0.32, websocket@^1.0.31: version "1.0.32" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" + resolved "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz" integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== dependencies: bufferutil "^4.0.1" @@ -13556,18 +13335,6 @@ websocket@1.0.32: utf-8-validate "^5.0.2" yaeti "^0.0.6" -websocket@^1.0.31: - version "1.0.34" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" - integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - whatwg-fetch@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" @@ -13575,15 +13342,15 @@ whatwg-fetch@^2.0.4: whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + integrity "sha1-lmRU6HZUYuN2RNNib2dCzotwll0= sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==" dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" whatwg-url@^8.4.0: version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz" integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" @@ -13592,7 +13359,7 @@ whatwg-url@^8.4.0: which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -13603,60 +13370,72 @@ which-boxed-primitive@^1.0.2: which-module@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + resolved "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz" + integrity "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==" which-module@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" + integrity "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" which@^2.0.1, which@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" wide-align@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" wide-align@^1.1.0: version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: string-width "^1.0.2 || 2 || 3 || 4" window-size@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= + resolved "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz" + integrity "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==" word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== wordwrap@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" + integrity "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" wordwrapjs@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + resolved "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz" integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== dependencies: reduce-flatten "^2.0.0" @@ -13664,20 +13443,20 @@ wordwrapjs@^4.0.0: workerpool@6.2.1: version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== wrap-ansi@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz" + integrity "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==" dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" wrap-ansi@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz" integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== dependencies: ansi-styles "^3.2.0" @@ -13686,7 +13465,7 @@ wrap-ansi@^5.1.0: wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" @@ -13695,7 +13474,7 @@ wrap-ansi@^6.2.0: wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -13704,12 +13483,12 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^2.4.2: version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz" integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== dependencies: graceful-fs "^4.1.11" @@ -13718,7 +13497,7 @@ write-file-atomic@^2.4.2: write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz" integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: imurmurhash "^0.1.4" @@ -13728,7 +13507,7 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: write-json-file@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" + resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz" integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== dependencies: detect-indent "^5.0.0" @@ -13740,7 +13519,7 @@ write-json-file@^3.2.0: write-json-file@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-4.3.0.tgz#908493d6fd23225344af324016e4ca8f702dd12d" + resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz" integrity sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ== dependencies: detect-indent "^6.0.0" @@ -13752,7 +13531,7 @@ write-json-file@^4.3.0: write-pkg@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" + resolved "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz" integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== dependencies: sort-keys "^2.0.0" @@ -13761,19 +13540,19 @@ write-pkg@^4.0.0: write@1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + resolved "https://registry.npmjs.org/write/-/write-1.0.3.tgz" integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: mkdirp "^0.5.1" -ws@7.4.6: +ws@7.4.6, ws@^7.4.6: version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== ws@^3.0.0: version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + resolved "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz" integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== dependencies: async-limiter "~1.0.0" @@ -13787,21 +13566,16 @@ ws@^5.1.1: dependencies: async-limiter "~1.0.0" -ws@^7.4.6: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== - xhr-request-promise@^0.1.2: version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + resolved "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz" integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== dependencies: xhr-request "^1.1.0" xhr-request@^1.0.1, xhr-request@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + resolved "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz" integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== dependencies: buffer-to-arraybuffer "^0.0.5" @@ -13814,14 +13588,14 @@ xhr-request@^1.0.1, xhr-request@^1.1.0: xhr2-cookies@1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + resolved "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz" integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= dependencies: cookiejar "^2.1.1" xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + resolved "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz" integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== dependencies: global "~4.4.0" @@ -13831,90 +13605,85 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: xmlhttprequest@1.8.0: version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= + resolved "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz" + integrity "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==" xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== xtend@~2.1.1: version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + resolved "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz" integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= dependencies: object-keys "~0.4.0" y18n@^3.2.1: version "3.2.2" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz" integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== y18n@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yaeti@^0.0.6: version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + resolved "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz" integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^1.10.0, yaml@^1.10.2: version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yargs-parser@13.1.2, yargs-parser@^13.1.2: version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@20.2.4: +yargs-parser@20.2.4, yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== yargs-parser@^2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz" + integrity "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==" dependencies: camelcase "^3.0.0" lodash.assign "^4.0.6" -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== - yargs-parser@^21.0.0: version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs-unparser@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz" integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== dependencies: flat "^4.1.0" @@ -13923,7 +13692,7 @@ yargs-unparser@1.6.0: yargs-unparser@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -13933,7 +13702,7 @@ yargs-unparser@2.0.0: yargs@13.3.2, yargs@^13.3.0: version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== dependencies: cliui "^5.0.0" @@ -13949,7 +13718,7 @@ yargs@13.3.2, yargs@^13.3.0: yargs@16.2.0, yargs@^16.2.0: version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -13962,7 +13731,7 @@ yargs@16.2.0, yargs@^16.2.0: yargs@^17.3.1: version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz" integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== dependencies: cliui "^7.0.2" @@ -13975,8 +13744,8 @@ yargs@^17.3.1: yargs@^4.7.1: version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA= + resolved "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz" + integrity "sha1-wMQpJMpKqmsObaFznfshZDn53cA= sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==" dependencies: cliui "^3.2.0" decamelize "^1.1.1" @@ -13995,15 +13764,15 @@ yargs@^4.7.1: yn@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zksync-web3@^0.8.1: version "0.8.1" - resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.8.1.tgz#db289d8f6caf61f4d5ddc471fa3448d93208dc14" + resolved "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.8.1.tgz" integrity sha512-1A4aHPQ3MyuGjpv5X/8pVEN+MdZqMjfVmiweQSRjOlklXYu65wT9BGEOtCmMs5d3gIvLp4ssfTeuR5OCKOD2kw== From b3bfe817a3c185544a37dc63d7784cf6c05152be Mon Sep 17 00:00:00 2001 From: test9955667 <79500129+test9955667@users.noreply.github.com> Date: Sun, 16 Apr 2023 21:23:29 -0500 Subject: [PATCH 04/25] Feat/charge fee (#163) * Create README.md * Update README.md * Update README.md * started concept for multiinvoker rollup optimization * Update README.md * Update README.md * changed visibility of invoker actions * adding testing for rollup invoker * finished unit tests of multiinvokerrollup * cleanup solidity + implement pr suggestions * update interface * deployment * wrap / unwrap prefixing fix * delete file * more style and comments * decode uint len < 32 check + more cleanup * more style * comment coverage * function visibility, mutability, ordering * comment formatting + coverage * more comment cleanup * more nitpicks * brizzle logical changes * move uint length check to relevant * move uint length check to relevant * fix pragma version * simplify function levels * simplify function levels * style changes * update cache storage scheme * deploy new proxy and impl * add isRollup util * handle both rollup and non rollup deployments * update rollup invoker * final sc cleanup * update deploy * update test * integration tests * more coverage * initial commit * charge fee changes * coverage + fixed tests * added error coverage and moved revert up level * update charge fee * add charge fee data to tests * test name misspelled * fix internal calls, update tests * remove .only * added coverage and debug charge fee * merge conflicts * added comments * added comments * added unwrapped charge fee action * test commit * test commit * address comments * fix multiinvoke test * swap wrapped for CHARGE_FEE * remove log * kevin cleanup --------- Co-authored-by: Kevin Britz Co-authored-by: Arjun Rao <2940142+arjun-io@users.noreply.github.com> --- .../contracts/interfaces/IMultiInvoker.sol | 3 +- .../contracts/multiinvoker/MultiInvoker.sol | 21 +++++++++ .../multiinvoker/MultiInvokerRollup.sol | 39 +++++++++++------ .../multiinvoker/multiInvoker.test.ts | 43 ++++++++++++++++++- .../multiinvoker/multiInvokerRollup.test.ts | 37 +++++++++++++++- .../unit/multiinvoker/MultiInvoker.test.ts | 11 ++++- .../multiinvoker/MultiInvokerRollup.test.ts | 19 +++++++- packages/perennial/test/util.ts | 19 ++++++++ yarn.lock | 5 +++ 9 files changed, 179 insertions(+), 18 deletions(-) diff --git a/packages/perennial/contracts/interfaces/IMultiInvoker.sol b/packages/perennial/contracts/interfaces/IMultiInvoker.sol index 62a9129b..116df91a 100644 --- a/packages/perennial/contracts/interfaces/IMultiInvoker.sol +++ b/packages/perennial/contracts/interfaces/IMultiInvoker.sol @@ -38,7 +38,8 @@ interface IMultiInvoker { VAULT_DEPOSIT, VAULT_REDEEM, VAULT_CLAIM, - VAULT_WRAP_AND_DEPOSIT + VAULT_WRAP_AND_DEPOSIT, + CHARGE_FEE } /// @dev Struct for action invocation diff --git a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol index 494641f0..5fa5c0f0 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol @@ -152,6 +152,12 @@ contract MultiInvoker is IMultiInvoker, UInitializable { (address account, IPerennialVault vault, UFixed18 amount) = abi.decode(invocation.args, (address, IPerennialVault, UFixed18)); _vaultWrapAndDeposit(account, vault, amount); } + + else if (invocation.action == PerennialAction.CHARGE_FEE) { + (address receiver, UFixed18 amount, bool wrapped) = abi.decode(invocation.args, (address, UFixed18, bool)); + + _chargeFee(receiver, amount, wrapped); + } } } @@ -363,4 +369,19 @@ contract MultiInvoker is IMultiInvoker, UInitializable { batcher.unwrap(amount, receiver); } } + + /** + * @notice Helper function to include an interface fee + * @param receiver The interface receiving the fee + * @param amount The amount of DSU to credit the interface + * @param wrapped Bool to specify is USDC is wrapped to DSU + */ + function _chargeFee(address receiver, UFixed18 amount, bool wrapped) internal { + if (wrapped) { + USDC.pull(msg.sender, amount); + _handleWrap(receiver, amount); + } else { + USDC.pullTo(msg.sender, receiver, amount); + } + } } diff --git a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol index e948d353..f560c4ba 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol @@ -77,7 +77,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { */ function _decodeFallbackAndInvoke(bytes calldata input) internal { PTR memory ptr; - + while (ptr.pos < input.length) { uint8 action = _readUint8(input, ptr); @@ -99,7 +99,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _closeTake(IProduct(product), amount); - } else if (action == 5) { // OPEN_MAKE + } else if (action == 5) { // OPEN_MAKE (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _openMake(IProduct(product), amount); @@ -107,12 +107,12 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _closeMake(IProduct(product), amount); - } else if (action == 7) { // CLAIM - (address product, uint256[] memory programIds) = + } else if (action == 7) { // CLAIM + (address product, uint256[] memory programIds) = (_readAndCacheAddress(input, ptr), _readUint256Array(input, ptr)); _claim(IProduct(product), programIds); - } else if (action == 8) { // WRAP + } else if (action == 8) { // WRAP (address receiver, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _wrap(receiver, amount); @@ -121,7 +121,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { _unwrap(receiver, amount); } else if (action == 10) { // WRAP_AND_DEPOSIT - (address account, address product, UFixed18 amount) = + (address account, address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _wrapAndDeposit(account, IProduct(product), amount); @@ -143,10 +143,14 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { (address owner, address vault) = (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr)); _vaultClaim(IPerennialVault(vault), owner); - } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT + } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT (address account, address vault, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _vaultWrapAndDeposit(account, IPerennialVault(vault), amount); + } else if (action == 16) { // CHARGE_FEE + (address receiver, UFixed18 amount, bool wrapped) = + (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr), _readBool(input, ptr)); + _chargeFee(receiver, amount, wrapped); } } } @@ -198,12 +202,23 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { } /** - * @notice Wraps next length of bytes as UFixed18 + * @notice Helper function to get bool from calldata * @param input Full calldata payload * @param ptr Current index of input to start decoding + * @return result The decoded bool + */ + function _readBool(bytes calldata input, PTR memory ptr) private pure returns (bool result) { + uint8 dir = _readUint8(input, ptr); + result = dir > 0; + } + + /** + * @notice Wraps next length of bytes as UFixed18 + * @param input Full calldata payload * @param ptr Current index of input to start decoding + * @return result The decoded UFixed18 */ - function _readUFixed18(bytes calldata input, PTR memory ptr) private pure returns (UFixed18 result) { + function _readUFixed18(bytes calldata input, PTR memory ptr) private pure returns (UFixed18 result) { return UFixed18.wrap(_readUint256(input, ptr)); } @@ -259,7 +274,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { } /** - * @dev This is called in decodeAccount and decodeProduct which both only pass 20 byte slices + * @dev This is called in decodeAccount and decodeProduct which both only pass 20 byte slices * @notice Unchecked force of 20 bytes into address * @param input The 20 bytes to be converted to address * @return result Address representation of `input` @@ -269,8 +284,8 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { result := mload(add(input, ADDRESS_LENGTH)) } } - - /** + + /** * @notice Unchecked loads arbitrarily-sized bytes into a uint * @dev Bytes length enforced as < max word size * @param input The bytes to convert to uint256 diff --git a/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts b/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts index 211d49d7..a99617f6 100644 --- a/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts +++ b/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { BigNumber, constants, utils } from 'ethers' import { MultiInvoker__factory, Product, TestnetVault, TestnetVault__factory } from '../../../types/generated' -import { IMultiInvoker } from '../../../types/generated/contracts/interfaces/IMultiInvoker' +import { IMultiInvoker } from '../../../types/generated/contracts/interfaces/IMultiInvoker.sol/IMultiInvoker' import { buildInvokerActions, InvokerAction } from '../../util' import { @@ -53,11 +53,13 @@ describe('MultiInvoker', () => { let product: Product let actions: { [action in InvokerAction]: IMultiInvoker.InvocationStruct } let partialActions: { [action in InvokerAction]: IMultiInvoker.InvocationStruct } + let actionsUnwrapped: { [action in InvokerAction]: IMultiInvoker.InvocationStruct } let position: BigNumber let amount: BigNumber let programs: number[] let vault: TestnetVault let vaultAmount: BigNumber + let feeAmount: BigNumber beforeEach(async () => { const { owner, user, dsu, usdc, usdcHolder, multiInvoker } = instanceVars @@ -75,6 +77,8 @@ describe('MultiInvoker', () => { amount = utils.parseEther('10000') programs = [PROGRAM_ID.toNumber()] vaultAmount = amount + feeAmount = utils.parseEther('10') + actions = buildInvokerActions({ userAddress: user.address, productAddress: product.address, @@ -83,13 +87,29 @@ describe('MultiInvoker', () => { programs, vaultAddress: vault.address, vaultAmount, + feeAmount: feeAmount, + wrappedFee: true, }) + partialActions = buildInvokerActions({ userAddress: user.address, productAddress: product.address, position: position.div(2), amount: amount.div(2), programs, + feeAmount: feeAmount, + }) + + actionsUnwrapped = buildInvokerActions({ + userAddress: user.address, + productAddress: product.address, + position, + amount, + programs, + vaultAddress: vault.address, + vaultAmount, + feeAmount: feeAmount, + wrappedFee: false, }) }) @@ -320,6 +340,27 @@ describe('MultiInvoker', () => { .withArgs(multiInvoker.address, user.address, 10000e6) }) + it(`sends unwrapped USDC in CHARGE_FEE action`, async () => { + const { user, multiInvoker, dsu, usdc } = instanceVars + + expect(await usdc.balanceOf(vault.address)).to.eq('0') + + await expect(multiInvoker.connect(user).invoke([actions.WRAP, actionsUnwrapped.CHARGE_FEE])).to.not.be.reverted + + expect(await usdc.balanceOf(vault.address)).to.eq(10e6) + }) + + it(`wraps USDC to DSU on WRAP action and invokes CHARGE_FEE to interface`, async () => { + const { user, multiInvoker, usdc, dsu } = instanceVars + + // // set + // await multiInvoker.connect(user).invoke([actionsUnwrapped.WRAP, actionsUnwrapped.UNWRAP]) + + await expect(multiInvoker.connect(user).invoke([actions.CHARGE_FEE])).to.not.be.reverted + + expect(await dsu.balanceOf(vault.address)).to.eq(utils.parseEther('10')) + }) + it('performs WITHDRAW_AND_UNWRAP', async () => { const { user, multiInvoker, batcher, usdc, collateral, reserve, dsu } = instanceVars diff --git a/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts b/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts index 009b3947..42f135f9 100644 --- a/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts +++ b/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts @@ -71,7 +71,6 @@ describe('MultiInvokerRollup', () => { beforeEach(async () => { const { owner, user, dsu, usdc, usdcHolder, multiInvokerRollup } = instanceVars - await usdc.connect(usdcHolder).transfer(user.address, 1_000_000e6) await usdc.connect(user).approve(multiInvokerRollup.address, constants.MaxUint256) await dsu.connect(user).approve(multiInvokerRollup.address, constants.MaxUint256) @@ -83,6 +82,7 @@ describe('MultiInvokerRollup', () => { position = utils.parseEther('0.001') amount = utils.parseEther('10000') + const feeAmount = utils.parseEther('10') programs = [PROGRAM_ID.toNumber()] vaultAmount = amount actions = buildInvokerActionRollup( @@ -95,6 +95,8 @@ describe('MultiInvokerRollup', () => { position, amount, vaultAmount, + feeAmount, + true, programs, ) @@ -108,6 +110,8 @@ describe('MultiInvokerRollup', () => { position.div(2), amount.div(2), vaultAmount, + feeAmount, + false, programs, ) @@ -121,6 +125,8 @@ describe('MultiInvokerRollup', () => { position, utils.parseEther('2000000'), vaultAmount, + feeAmount, + false, programs, ) }) @@ -380,6 +386,35 @@ describe('MultiInvokerRollup', () => { .withArgs(multiInvokerRollup.address, user.address, 10000e6) }) + it(`sends unwrapped USDC in CHARGE_FEE action`, async () => { + const { user, multiInvokerRollup, dsu, usdc } = instanceVars + + expect(await usdc.balanceOf(vault.address)).to.eq('0') + + const res = user.sendTransaction( + buildTransactionRequest( + user, + multiInvokerRollup, + `0x` + actions.WRAP.payload + customActions.CHARGE_FEE.payload, + ), + ) + + await expect(res).to.not.be.reverted + + expect(await usdc.balanceOf(vault.address)).to.eq(10e6) + }) + + it(`wraps USDC to DSU on WRAP action and invokes CHARGE_FEE to interface `, async () => { + const { user, multiInvokerRollup, usdc, dsu } = instanceVars + + const res = user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CHARGE_FEE.payload), + ) + + await expect(res).to.not.be.reverted + expect(await dsu.balanceOf(vault.address)).to.eq(utils.parseEther('10')) + }) + it('performs WITHDRAW_AND_UNWRAP', async () => { const { user, multiInvokerRollup, batcher, usdc, collateral, reserve } = instanceVars diff --git a/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts b/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts index f59d8798..d9b339bf 100644 --- a/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts +++ b/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts @@ -16,7 +16,7 @@ import { IBatcher, TestnetVault, } from '../../../types/generated' -import { IMultiInvoker } from '../../../types/generated/contracts/interfaces/IMultiInvoker' +import { IMultiInvoker } from '../../../types/generated/contracts/interfaces/IMultiInvoker.sol/IMultiInvoker' import { InvokerAction, buildInvokerActions } from '../../util' import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' @@ -116,6 +116,7 @@ describe('MultiInvoker', () => { let actions: { [action in InvokerAction]: IMultiInvoker.InvocationStruct } const amount = utils.parseEther('100') const usdcAmount = 100e6 + const feeAmount = utils.parseEther('10') const position = utils.parseEther('12') const programs = [1, 2, 3] const vaultAmount = utils.parseEther('567') @@ -130,6 +131,7 @@ describe('MultiInvoker', () => { programs, vaultAddress: vault.address, vaultAmount, + feeAmount: feeAmount, }) dsu.transferFrom.whenCalledWith(user.address, multiInvoker.address, amount).returns(true) usdc.transferFrom.whenCalledWith(user.address, multiInvoker.address, usdcAmount).returns(true) @@ -307,7 +309,10 @@ describe('MultiInvoker', () => { }) it('performs a multi invoke', async () => { - await expect(multiInvoker.connect(user).invoke(Object.values(actions))).to.not.be.reverted + // do not attemp to chage fee in unit tests + const actionsLessChargeFee = Object.values(actions).slice(0, -1) + + await expect(multiInvoker.connect(user).invoke(actionsLessChargeFee)).to.not.be.reverted // Deposit/Withdraw expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) @@ -389,6 +394,7 @@ describe('MultiInvoker', () => { let actions: { [action in InvokerAction]: IMultiInvoker.InvocationStruct } const amount = utils.parseEther('100') const usdcAmount = 100e6 + const feeAmount = utils.parseEther('10') const position = utils.parseEther('12') const programs = [1, 2, 3] @@ -399,6 +405,7 @@ describe('MultiInvoker', () => { position, amount, programs, + feeAmount: feeAmount, }) dsu.transferFrom.whenCalledWith(user.address, multiInvoker.address, amount).returns(true) usdc.transferFrom.whenCalledWith(user.address, multiInvoker.address, usdcAmount).returns(true) diff --git a/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts b/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts index 094459ea..2ab25a40 100644 --- a/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts +++ b/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts @@ -112,6 +112,7 @@ describe('MultiInvokerRollup', () => { let actions: { [action in InvokerAction]: { action: BigNumberish; payload: string } } let zeroAction: { [action in InvokerAction]: { action: BigNumberish; payload: string } } const amount = utils.parseEther('100') + const feeAmount = utils.parseEther('10') const usdcAmount = 100e6 const position = utils.parseEther('12') const programs = [1, 2, 3] @@ -129,6 +130,8 @@ describe('MultiInvokerRollup', () => { position, amount, vaultAmount, + feeAmount, + false, programs, ) @@ -142,6 +145,8 @@ describe('MultiInvokerRollup', () => { position, 0, vaultAmount, + feeAmount, + false, programs, ) @@ -162,6 +167,7 @@ describe('MultiInvokerRollup', () => { it('reverts with custom errors with bad calldata', async () => { // store product in cache + await expect( user.sendTransaction( buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), @@ -393,8 +399,11 @@ describe('MultiInvokerRollup', () => { }) it('performs a multi invoke', async () => { + // do not attempt charge fee in unit tests + const actionsLessChargeFee = Object.values(actions).slice(0, -1) + const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, buildAllActionsRollup(Object.values(actions))), + buildTransactionRequest(user, multiInvokerRollup, buildAllActionsRollup(actionsLessChargeFee)), ) await expect(res).to.not.be.reverted @@ -481,6 +490,7 @@ describe('MultiInvokerRollup', () => { const usdcAmount = 100e6 const position = utils.parseEther('12') const VaultAmount = utils.parseEther('567') + const feeAmount = utils.parseEther('10') const programs = [1, 2, 3] beforeEach(() => { @@ -494,6 +504,8 @@ describe('MultiInvokerRollup', () => { position, amount, VaultAmount, + feeAmount, + false, programs, ) dsu.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, amount).returns(true) @@ -558,6 +570,7 @@ describe('MultiInvokerRollup', () => { const usdcAmount = 100e6 const position = utils.parseEther('12') const VaultAmount = utils.parseEther('567') + const feeAmount = utils.parseEther('10') const programs = [1, 2, 3] beforeEach(() => { @@ -571,6 +584,8 @@ describe('MultiInvokerRollup', () => { position, amount, VaultAmount, + feeAmount, + false, programs, ) actionsCached = buildInvokerActionRollup( @@ -583,6 +598,8 @@ describe('MultiInvokerRollup', () => { position, amount, VaultAmount, + feeAmount, + false, programs, ) diff --git a/packages/perennial/test/util.ts b/packages/perennial/test/util.ts index 72fff8b4..2d2602ea 100644 --- a/packages/perennial/test/util.ts +++ b/packages/perennial/test/util.ts @@ -19,6 +19,7 @@ export type InvokerAction = | 'VAULT_REDEEM' | 'VAULT_CLAIM' | 'VAULT_WRAP_AND_DEPOSIT' + | 'CHARGE_FEE' export const buildInvokerActions = ({ userAddress, @@ -28,6 +29,8 @@ export const buildInvokerActions = ({ programs, vaultAddress = constants.AddressZero, vaultAmount = 0, + feeAmount, + wrappedFee, }: { userAddress: string productAddress: string @@ -36,6 +39,8 @@ export const buildInvokerActions = ({ programs: number[] vaultAddress?: string vaultAmount?: BigNumberish + feeAmount?: BigNumberish + wrappedFee?: boolean }): { [action in InvokerAction]: IMultiInvoker.InvocationStruct } => { return { NOOP: { @@ -102,6 +107,10 @@ export const buildInvokerActions = ({ action: 15, args: utils.defaultAbiCoder.encode(['address', 'address', 'uint'], [userAddress, vaultAddress, vaultAmount]), }, + CHARGE_FEE: { + action: 16, + args: utils.defaultAbiCoder.encode(['address', 'uint', 'bool'], [vaultAddress, feeAmount, wrappedFee]), + }, } } @@ -144,6 +153,8 @@ export const buildInvokerActionRollup = ( position?: BigNumberish, amount?: BigNumberish, vaultAmount?: BigNumberish, + feeAmount?: BigNumberish, + wrappedFee?: boolean, programs?: number[], ): { [action in InvokerAction]: { action: BigNumberish; payload: string } } => { return { @@ -247,6 +258,14 @@ export const buildInvokerActionRollup = ( encodeAddressOrCacheIndex(vaultCache, vaultAddress) + encodeUint(BigNumber.from(vaultAmount)), }, + CHARGE_FEE: { + action: 16, + payload: + `10` + + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + + encodeUint(BigNumber.from(feeAmount)) + + (wrappedFee ? `01` : `00`), + }, } } diff --git a/yarn.lock b/yarn.lock index d5596d41..4d058bc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6086,6 +6086,11 @@ extsprintf@1.3.0: resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" integrity "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fake-merkle-patricia-tree@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz" From 29962748b9fb147f0ea277e8857772360cae43a0 Mon Sep 17 00:00:00 2001 From: Kevin Britz Date: Sun, 16 Apr 2023 19:26:37 -0700 Subject: [PATCH 05/25] Multi-Asset Vault (#162) * Refactor into struct Signed-off-by: Fennel <0xfennel@proton.me> * Initial implementation pass * Change events * Quick changes to compiler settings * Move around test files * Get rid of _deposit * Fix interface * Fix existing tests, along with some bugs * Add addMarket() and updateWeight() Signed-off-by: Fennel <0xfennel@proton.me> * fix build * immutable definition rework * remove erc20 * market account type * add perennial lib * epoch rewrite * TODOs * clean up current speoch * fix asset snapshotting * existing tests working * re-combine logic * make static storage multi-asset * basic multi-asset test * make upgrade compatible * equivalent multi-asset tests * todos * add stale epoch fix * starting pending tests * fix epoch stamping issue * TODOs * fix takerlimit tests * add upgrade note * run optimizer always in vaults * add epoch getters --------- Signed-off-by: Fennel <0xfennel@proton.me> Co-authored-by: Fennel <0xfennel@proton.me> Co-authored-by: Arjun Rao <2940142+arjun-io@users.noreply.github.com> --- package.json | 2 +- .../contracts/BalancedVault.sol | 693 -------- .../contracts/balanced/BalancedVault.sol | 808 ++++++++++ .../balanced/BalancedVaultDefinition.sol | 110 ++ .../contracts/interfaces/IBalancedVault.sol | 49 +- .../interfaces/IBalancedVaultDefinition.sol | 24 + packages/perennial-vaults/hardhat.config.ts | 41 +- packages/perennial-vaults/package.json | 2 +- .../{ => BalancedVault}/balancedVault.test.ts | 352 ++--- .../BalancedVault/balancedVaultMulti.test.ts | 1407 +++++++++++++++++ .../test/integration/helpers/setupHelpers.ts | 33 +- yarn.lock | 10 +- 12 files changed, 2524 insertions(+), 1007 deletions(-) delete mode 100644 packages/perennial-vaults/contracts/BalancedVault.sol create mode 100644 packages/perennial-vaults/contracts/balanced/BalancedVault.sol create mode 100644 packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol create mode 100644 packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol rename packages/perennial-vaults/test/integration/{ => BalancedVault}/balancedVault.test.ts (77%) create mode 100644 packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts diff --git a/package.json b/package.json index 8d8c2ec2..70cd9ca2 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "ethers": "^5.7.2", "graphql": "^16.6.0", "graphql-request": "^5.2.0", - "hardhat": "^2.12.2", + "hardhat": "^2.13.0", "hardhat-contract-sizer": "^2.4.0", "hardhat-dependency-compiler": "^1.1.2", "hardhat-deploy": "^0.11.4", diff --git a/packages/perennial-vaults/contracts/BalancedVault.sol b/packages/perennial-vaults/contracts/BalancedVault.sol deleted file mode 100644 index 796f2b2f..00000000 --- a/packages/perennial-vaults/contracts/BalancedVault.sol +++ /dev/null @@ -1,693 +0,0 @@ -//SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.17; - -import "./interfaces/IBalancedVault.sol"; -import "@equilibria/root/control/unstructured/UInitializable.sol"; -import "@openzeppelin/contracts/utils/math/Math.sol"; - -/** - * @title BalancedVault - * @notice ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial. - * @dev Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to - * maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap - * the maximum amount of assets in the vault. - * - * The vault has a "delayed mint" mechanism for shares on deposit. After depositing to the vault, a user must wait - * until the next settlement of the underlying products in order for shares to be reflected in the getters. - * The shares will be fully reflected in contract state when the next settlement occurs on the vault itself. - * Similarly, when redeeming shares, underlying assets are not claimable until a settlement occurs. - * Each state changing interaction triggers the `settle` flywheel in order to bring the vault to the - * desired state. - * In the event that there is not a settlement for a long period of time, keepers can call the `sync` method to - * force settlement and rebalancing. This is most useful to prevent vault liquidation due to PnL changes - * causing the vault to be in an unhealthy state (far away from target leverage) - */ -contract BalancedVault is IBalancedVault, UInitializable { - UFixed18 constant private TWO = UFixed18.wrap(2e18); - - /// @dev The address of the Perennial controller contract - IController public immutable controller; - - /// @dev The address of the Perennial collateral contract - ICollateral public immutable collateral; - - /// @dev The address of the Perennial product on the long side - IProduct public immutable long; - - /// @dev The address of the Perennial product on the short side - IProduct public immutable short; - - /// @dev The target leverage amount for the vault - UFixed18 public immutable targetLeverage; - - /// @dev The collateral cap for the vault - UFixed18 public immutable maxCollateral; - - /// @dev The underlying asset of the vault - Token18 public immutable asset; - - /// @dev The ERC20 name of the vault - string public name; - - /// @dev The ERC20 symbol of the vault - string public symbol; - - /// @dev Mapping of allowance across all users - mapping(address => mapping(address => UFixed18)) public allowance; - - /// @dev Mapping of shares of the vault per user - mapping(address => UFixed18) private _balanceOf; - - /// @dev Total number of shares across all users - UFixed18 private _totalSupply; - - /// @dev Mapping of unclaimed underlying of the vault per user - mapping(address => UFixed18) private _unclaimed; - - /// @dev Mapping of unclaimed underlying of the vault per user - UFixed18 private _totalUnclaimed; - - /// @dev Deposits that have not been settled, or have been settled but not yet processed by this contract - UFixed18 private _deposit; - - /// @dev Redemptions that have not been settled, or have been settled but not yet processed by this contract - UFixed18 private _redemption; - - /// @dev The latest version that a pending deposit or redemption has been placed - uint256 private _latestVersion; - - /// @dev Mapping of pending (not yet converted to shares) per user - mapping(address => UFixed18) private _deposits; - - /// @dev Mapping of pending (not yet withdrawn) per user - mapping(address => UFixed18) private _redemptions; - - /// @dev Mapping of the latest version that a pending deposit or redemption has been placed per user - mapping(address => uint256) private _latestVersions; - - /// @dev Mapping of versions of the vault state at a given oracle version - mapping(uint256 => Version) private _versions; - - constructor( - Token18 asset_, - IController controller_, - IProduct long_, - IProduct short_, - UFixed18 targetLeverage_, - UFixed18 maxCollateral_ - ) { - asset = asset_; - controller = controller_; - collateral = controller_.collateral(); - long = long_; - short = short_; - targetLeverage = targetLeverage_; - maxCollateral = maxCollateral_; - } - - /** - * @notice Initializes the contract state - * @param name_ ERC20 asset name - * @param symbol_ ERC20 asset symbol - */ - function initialize(string memory name_, string memory symbol_) external initializer(1) { - name = name_; - symbol = symbol_; - - asset.approve(address(collateral)); - } - - /** - * @notice Rebalances the collateral and position of the vault without a deposit or withdraw - * @dev Should be called by a keeper when the vault approaches a liquidation state on either side - */ - function sync() external { - (VersionContext memory context, ) = _settle(address(0)); - _rebalance(context, UFixed18Lib.ZERO); - } - - /** - * @notice Deposits `assets` assets into the vault, returning shares to `account` after the deposit settles. - * @param assets The amount of assets to deposit - * @param account The account to deposit on behalf of - */ - function deposit(UFixed18 assets, address account) external { - (VersionContext memory context, ) = _settle(account); - if (assets.gt(_maxDepositAtVersion(context))) revert BalancedVaultDepositLimitExceeded(); - - _deposit = _deposit.add(assets); - _latestVersion = context.version; - _deposits[account] = _deposits[account].add(assets); - _latestVersions[account] = context.version; - emit Deposit(msg.sender, account, context.version, assets); - - asset.pull(msg.sender, assets); - - _rebalance(context, UFixed18Lib.ZERO); - } - - /** - * @notice Redeems `shares` shares from the vault - * @dev Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets - * If account is not msg.sender, requires prior spending approval - * @param shares The amount of shares to redeem - * @param account The account to redeem on behalf of - */ - function redeem(UFixed18 shares, address account) external { - if (msg.sender != account) _consumeAllowance(account, msg.sender, shares); - - (VersionContext memory context, VersionContext memory accountContext) = _settle(account); - if (shares.gt(_maxRedeemAtVersion(context, accountContext, account))) revert BalancedVaultRedemptionLimitExceeded(); - - _redemption = _redemption.add(shares); - _latestVersion = context.version; - _redemptions[account] = _redemptions[account].add(shares); - _latestVersions[account] = context.version; - emit Redemption(msg.sender, account, context.version, shares); - - _burn(account, shares); - - _rebalance(context, UFixed18Lib.ZERO); - } - - /** - * @notice Claims all claimable assets for account, sending assets to account - * @param account The account to claim for - */ - function claim(address account) external { - (VersionContext memory context, ) = _settle(account); - - UFixed18 unclaimedAmount = _unclaimed[account]; - UFixed18 unclaimedTotal = _totalUnclaimed; - _unclaimed[account] = UFixed18Lib.ZERO; - _totalUnclaimed = unclaimedTotal.sub(unclaimedAmount); - emit Claim(msg.sender, account, unclaimedAmount); - - // pro-rate if vault has less collateral than unclaimed - UFixed18 claimAmount = unclaimedAmount; - (UFixed18 longCollateral, UFixed18 shortCollateral, UFixed18 idleCollateral) = _collateral(); - UFixed18 totalCollateral = longCollateral.add(shortCollateral).add(idleCollateral); - if (totalCollateral.lt(unclaimedTotal)) claimAmount = claimAmount.muldiv(totalCollateral, unclaimedTotal); - - _rebalance(context, claimAmount); - - asset.push(account, claimAmount); - } - - /** - * @notice Sets `amount` as the allowance of `spender` over the caller's shares - * @param spender Address which can spend operate on shares - * @param amount Amount of shares that spender can operate on - * @return bool true if the approval was successful, otherwise reverts - */ - function approve(address spender, UFixed18 amount) external returns (bool) { - allowance[msg.sender][spender] = amount; - emit Approval(msg.sender, spender, amount); - return true; - } - - /** - * @notice Moves `amount` shares from the caller's account to `to` - * @param to Address to send shares to - * @param amount Amount of shares to send - * @return bool true if the transfer was successful, otherwise reverts - */ - function transfer(address to, UFixed18 amount) external returns (bool) { - _settle(msg.sender); - _transfer(msg.sender, to, amount); - return true; - } - - /** - * @notice Moves `amount` shares from `from to `to` - * @param from Address to send shares from - * @param to Address to send shares to - * @param amount Amount of shares to send - * @return bool true if the transfer was successful, otherwise reverts - */ - function transferFrom(address from, address to, UFixed18 amount) external returns (bool) { - _settle(from); - _consumeAllowance(from, msg.sender, amount); - _transfer(from, to, amount); - return true; - } - - /** - * @notice Returns the decimals places of the share token - * @return Decimal places of the share share token - */ - function decimals() external pure returns (uint8) { - return 18; - } - - /** - * @notice The maximum available deposit amount - * @dev Only exact when vault is synced, otherwise approximate - * @return Maximum available deposit amount - */ - function maxDeposit(address) external view returns (UFixed18) { - (VersionContext memory context, ) = _loadContextForRead(address(0)); - return _maxDepositAtVersion(context); - } - - /** - * @notice The maximum available redeemable amount - * @dev Only exact when vault is synced, otherwise approximate - * @param account The account to redeem for - * @return Maximum available redeemable amount - */ - function maxRedeem(address account) external view returns (UFixed18) { - (VersionContext memory context, VersionContext memory accountContext) = _loadContextForRead(account); - return _maxRedeemAtVersion(context, accountContext, account); - } - - /** - * @notice The total amount of assets currently held by the vault - * @return Amount of assets held by the vault - */ - function totalAssets() external view returns (UFixed18) { - (VersionContext memory context, ) = _loadContextForRead(address(0)); - return _totalAssetsAtVersion(context); - } - - /** - * @notice The total amount of shares currently issued - * @return Amount of shares currently issued - */ - function totalSupply() external view returns (UFixed18) { - (VersionContext memory context, ) = _loadContextForRead(address(0)); - return _totalSupplyAtVersion(context); - } - - /** - * @notice Number of shares held by `account` - * @param account Account to query balance of - * @return Number of shares held by `account` - */ - function balanceOf(address account) external view returns (UFixed18) { - (, VersionContext memory accountContext) = _loadContextForRead(account); - return _balanceOfAtVersion(accountContext, account); - } - - /** - * @notice Total unclaimed assets in vault - * @return Total unclaimed assets in vault - */ - function totalUnclaimed() external view returns (UFixed18) { - (VersionContext memory context, ) = _loadContextForRead(address(0)); - return _totalUnclaimedAtVersion(context); - } - - /** - * @notice `account`'s unclaimed assets - * @param account Account to query unclaimed balance of - * @return `account`'s unclaimed assets - */ - function unclaimed(address account) external view returns (UFixed18) { - (, VersionContext memory accountContext) = _loadContextForRead(account); - return _unclaimedAtVersion(accountContext, account); - } - - /** - * @notice Converts a given amount of assets to shares - * @param assets Number of assets to convert to shares - * @return Amount of shares for the given assets - */ - function convertToShares(UFixed18 assets) external view returns (UFixed18) { - (VersionContext memory context, ) = _loadContextForRead(address(0)); - (context.latestCollateral, context.latestShares) = - (_totalAssetsAtVersion(context), _totalSupplyAtVersion(context)); - return _convertToSharesAtVersion(context, assets); - } - - /** - * @notice Converts a given amount of shares to assets - * @param shares Number of shares to convert to assets - * @return Amount of assets for the given shares - */ - function convertToAssets(UFixed18 shares) external view returns (UFixed18) { - (VersionContext memory context, ) = _loadContextForRead(address(0)); - (context.latestCollateral, context.latestShares) = - (_totalAssetsAtVersion(context), _totalSupplyAtVersion(context)); - return _convertToAssetsAtVersion(context, shares); - } - - /** - * @notice Hook that is called before every stateful operation - * @dev Settles the vault's account on both the long and short product, along with any global or user-specific deposits/redemptions - * @param account The account that called the operation, or 0 if called by a keeper. - * @return context The current version context - */ - function _settle(address account) private returns (VersionContext memory context, VersionContext memory accountContext) { - (context, accountContext) = _loadContextForWrite(account); - - if (context.version > _latestVersion) { - _delayedMint(_totalSupplyAtVersion(context).sub(_totalSupply)); - _totalUnclaimed = _totalUnclaimedAtVersion(context); - _deposit = UFixed18Lib.ZERO; - _redemption = UFixed18Lib.ZERO; - _latestVersion = context.version; - - _versions[context.version] = Version({ - longPosition: long.position(address(this)).maker, - shortPosition: short.position(address(this)).maker, - totalShares: _totalSupply, - longAssets: collateral.collateral(address(this), long), - shortAssets: collateral.collateral(address(this), short), - totalAssets: _totalAssetsAtVersion(context) - }); - } - - if (account != address(0) && accountContext.version > _latestVersions[account]) { - _delayedMintAccount(account, _balanceOfAtVersion(accountContext, account).sub(_balanceOf[account])); - _unclaimed[account] = _unclaimedAtVersion(accountContext, account); - _deposits[account] = UFixed18Lib.ZERO; - _redemptions[account] = UFixed18Lib.ZERO; - _latestVersions[account] = accountContext.version; - } - } - - /** - * @notice Rebalances the collateral and position of the vault - * @dev Rebalance is executed on best-effort, any failing legs of the strategy will not cause a revert - * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation - */ - function _rebalance(VersionContext memory context, UFixed18 claimAmount) private { - _rebalanceCollateral(claimAmount); - _rebalancePosition(context, claimAmount); - } - - /** - * @notice Rebalances the collateral of the vault - * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation - */ - function _rebalanceCollateral(UFixed18 claimAmount) private { - (UFixed18 longCollateral, UFixed18 shortCollateral, UFixed18 idleCollateral) = _collateral(); - UFixed18 currentCollateral = longCollateral.add(shortCollateral).add(idleCollateral).sub(claimAmount); - UFixed18 targetCollateral = currentCollateral.div(TWO); - if (targetCollateral.lt(controller.minCollateral())) targetCollateral = UFixed18Lib.ZERO; - - (IProduct greaterProduct, IProduct lesserProduct) = - longCollateral.gt(shortCollateral) ? (long, short) : (short, long); - - _updateCollateral(greaterProduct, greaterProduct == long ? longCollateral : shortCollateral, targetCollateral); - _updateCollateral(lesserProduct, lesserProduct == long ? longCollateral : shortCollateral, targetCollateral); - } - - /** - * @notice Rebalances the position of the vault - */ - function _rebalancePosition(VersionContext memory context, UFixed18 claimAmount) private { - UFixed18 currentAssets = _totalAssetsAtVersion(context).sub(claimAmount); - UFixed18 currentUtilized = _totalSupply.add(_redemption).isZero() ? - _deposit.add(currentAssets) : - _deposit.add(currentAssets.muldiv(_totalSupply, _totalSupply.add(_redemption))); - if (currentUtilized.lt(controller.minCollateral().mul(TWO))) currentUtilized = UFixed18Lib.ZERO; - - UFixed18 currentPrice = long.atVersion(context.version).price.abs(); - UFixed18 targetPosition = currentUtilized.mul(targetLeverage).div(currentPrice).div(TWO); - - _updateMakerPosition(long, targetPosition); - _updateMakerPosition(short, targetPosition); - } - - /** - * @notice Adjusts the collateral on `product` to `targetCollateral` - * @param product The product to adjust the vault's collateral on - * @param currentCollateral The current collateral of the product - * @param targetCollateral The new collateral to target - */ - function _updateCollateral(IProduct product, UFixed18 currentCollateral, UFixed18 targetCollateral) private { - if (currentCollateral.gt(targetCollateral)) - collateral.withdrawTo(address(this), product, currentCollateral.sub(targetCollateral)); - if (currentCollateral.lt(targetCollateral)) - collateral.depositTo(address(this), product, targetCollateral.sub(currentCollateral)); - - emit CollateralUpdated(product, targetCollateral); - } - - /** - * @notice Adjusts the position on `product` to `targetPosition` - * @param product The product to adjust the vault's position on - * @param targetPosition The new position to target - */ - function _updateMakerPosition(IProduct product, UFixed18 targetPosition) private { - UFixed18 currentPosition = product.position(address(this)).next(product.pre(address(this))).maker; - UFixed18 currentMaker = product.positionAtVersion(product.latestVersion()).next(product.pre()).maker; - UFixed18 makerLimit = product.makerLimit(); - UFixed18 makerAvailable = makerLimit.gt(currentMaker) ? makerLimit.sub(currentMaker) : UFixed18Lib.ZERO; - - if (targetPosition.lt(currentPosition)) - product.closeMake(currentPosition.sub(targetPosition)); - if (targetPosition.gt(currentPosition)) - product.openMake(targetPosition.sub(currentPosition).min(makerAvailable)); - - emit PositionUpdated(product, targetPosition); - } - - /** - * @notice Moves `amount` shares from `from` to `to` - * @param from Address to send shares from - * @param to Address to send shares to - * @param amount Amount of shares to move - */ - function _transfer(address from, address to, UFixed18 amount) private { - _balanceOf[from] = _balanceOf[from].sub(amount); - _balanceOf[to] = _balanceOf[to].add(amount); - emit Transfer(from, to, amount); - } - - /** - * @notice Burns `amount` shares from `from`, adjusting totalSupply - * @param from Address to burn shares from - * @param amount Amount of shares to burn - */ - function _burn(address from, UFixed18 amount) private { - _balanceOf[from] = _balanceOf[from].sub(amount); - _totalSupply = _totalSupply.sub(amount); - emit Transfer(from, address(0), amount); - } - - /** - * @notice Mints `amount` shares, adjusting totalSupply - * @param amount Amount of shares to mint - */ - function _delayedMint(UFixed18 amount) private { - _totalSupply = _totalSupply.add(amount); - } - - /** - * @notice Mints `amount` shares to `to` - * @param to Address to mint shares to - * @param amount Amount of shares to mint - */ - function _delayedMintAccount(address to, UFixed18 amount) private { - _balanceOf[to] = _balanceOf[to].add(amount); - emit Transfer(address(0), to, amount); - } - - /** - * @notice Decrements `spender`s allowance for `account` by `amount` - * @dev Does not decrement if approval is for -1 - * @param account Address of allower - * @param spender Address of spender - * @param amount Amount to decrease allowance by - */ - function _consumeAllowance(address account, address spender, UFixed18 amount) private { - if (allowance[account][spender].eq(UFixed18Lib.MAX)) return; - allowance[account][spender] = allowance[account][spender].sub(amount); - } - - /** - * @notice Loads the context for the given `account`, settling the vault first - * @param account Account to load the context for - * @return global version context - * @return account version context - */ - function _loadContextForWrite(address account) private returns (VersionContext memory, VersionContext memory) { - long.settleAccount(address(this)); - short.settleAccount(address(this)); - uint256 currentVersion = long.latestVersion(address(this)); - - return ( - VersionContext(currentVersion, _assetsAt(_latestVersion), _sharesAt(_latestVersion)), - VersionContext(currentVersion, _assetsAt(_latestVersions[account]), _sharesAt(_latestVersions[account])) - ); - } - - /** - * @notice Loads the context for the given `account` - * @param account Account to load the context for - * @return global version context - * @return account version context - */ - function _loadContextForRead(address account) private view returns (VersionContext memory, VersionContext memory) { - uint256 currentVersion = Math.min(long.latestVersion(), short.latestVersion()); // latest version that both products are settled to - - return ( - VersionContext(currentVersion, _assetsAt(_latestVersion), _sharesAt(_latestVersion)), - VersionContext(currentVersion, _assetsAt(_latestVersions[account]), _sharesAt(_latestVersions[account])) - ); - } - - /** - * @notice Calculates whether or not the vault is in an unhealthy state at the provided version - * @param context Version context to calculate health - * @return bool true if unhealthy, false if healthy - */ - function _unhealthyAtVersion(VersionContext memory context) private view returns (bool) { - return collateral.liquidatable(address(this), long) - || collateral.liquidatable(address(this), short) - || long.isLiquidating(address(this)) - || short.isLiquidating(address(this)) - || (!context.latestShares.isZero() && context.latestCollateral.isZero()); - } - - /** - * @notice The maximum available deposit amount at the given version - * @param context Version context to use in calculation - * @return Maximum available deposit amount at version - */ - function _maxDepositAtVersion(VersionContext memory context) private view returns (UFixed18) { - if (_unhealthyAtVersion(context)) return UFixed18Lib.ZERO; - UFixed18 currentCollateral = _totalAssetsAtVersion(context).add(_deposit); - return maxCollateral.gt(currentCollateral) ? maxCollateral.sub(currentCollateral) : UFixed18Lib.ZERO; - } - - /** - * @notice The maximum available redeemable amount at the given version for `account` - * @param context Version context to use in calculation - * @param accountContext Account version context to use in calculation - * @param account Account to calculate redeemable amount - * @return Maximum available redeemable amount at version - */ - function _maxRedeemAtVersion( - VersionContext memory context, - VersionContext memory accountContext, - address account - ) private view returns (UFixed18) { - if (_unhealthyAtVersion(context)) return UFixed18Lib.ZERO; - return _balanceOfAtVersion(accountContext, account); - } - - /** - * @notice The total assets at the given version - * @param context Version context to use in calculation - * @return Total assets amount at version - */ - function _totalAssetsAtVersion(VersionContext memory context) private view returns (UFixed18) { - (UFixed18 longCollateral, UFixed18 shortCollateral, UFixed18 idleCollateral) = _collateral(); - (UFixed18 totalCollateral, UFixed18 totalDebt) = - (longCollateral.add(shortCollateral).add(idleCollateral), _totalUnclaimedAtVersion(context).add(_deposit)); - return totalCollateral.gt(totalDebt) ? totalCollateral.sub(totalDebt) : UFixed18Lib.ZERO; - } - - /** - * @notice The total supply at the given version - * @param context Version context to use in calculation - * @return Total supply amount at version - */ - function _totalSupplyAtVersion(VersionContext memory context) private view returns (UFixed18) { - if (context.version == _latestVersion) return _totalSupply; - return _totalSupply.add(_convertToSharesAtVersion(context, _deposit)); - } - - /** - * @notice The balance of `account` at the given version - * @param accountContext Account version context to use in calculation - * @param account Account to calculate balance of amount - * @return Account balance at version - */ - function _balanceOfAtVersion(VersionContext memory accountContext, address account) private view returns (UFixed18) { - if (accountContext.version == _latestVersions[account]) return _balanceOf[account]; - return _balanceOf[account].add(_convertToSharesAtVersion(accountContext, _deposits[account])); - } - - /** - * @notice The total unclaimed assets at the given version - * @param context Version context to use in calculation - * @return Total unclaimed asset amount at version - */ - function _totalUnclaimedAtVersion(VersionContext memory context) private view returns (UFixed18) { - if (context.version == _latestVersion) return _totalUnclaimed; - return _totalUnclaimed.add(_convertToAssetsAtVersion(context, _redemption)); - } - - /** - * @notice The total unclaimed assets at the given version for `account` - * @param accountContext Account version context to use in calculation - * @param account Account to calculate unclaimed assets for - * @return Total unclaimed asset amount for `account` at version - */ - function _unclaimedAtVersion(VersionContext memory accountContext, address account) private view returns (UFixed18) { - if (accountContext.version == _latestVersions[account]) return _unclaimed[account]; - return _unclaimed[account].add(_convertToAssetsAtVersion(accountContext, _redemptions[account])); - } - - /** - * @notice Returns the amounts of the individual sources of assets in the vault - * @return The amount of collateral in the long product - * @return The amount of collateral in the short product - * @return The amount of collateral idle in the vault contract - */ - function _collateral() private view returns (UFixed18, UFixed18, UFixed18) { - return ( - collateral.collateral(address(this), long), - collateral.collateral(address(this), short), - asset.balanceOf() - ); - } - - /** - * @notice The total assets at the given version - * @dev Calculates and adds accumulated PnL for `version` + 1 - * @param version Version to get total assets at - * @return Total assets in the vault at the given version - */ - function _assetsAt(uint256 version) private view returns (UFixed18) { - Fixed18 longAccumulated = long.valueAtVersion(version + 1).maker.sub(long.valueAtVersion(version).maker) - .mul(Fixed18Lib.from(_versions[version].longPosition)) - .max(Fixed18Lib.from(_versions[version].longAssets).mul(Fixed18Lib.NEG_ONE)); // collateral can't go negative on a product - Fixed18 shortAccumulated = short.valueAtVersion(version + 1).maker.sub(short.valueAtVersion(version).maker) - .mul(Fixed18Lib.from(_versions[version].shortPosition)) - .max(Fixed18Lib.from(_versions[version].shortAssets).mul(Fixed18Lib.NEG_ONE)); // collateral can't go negative on a product - - return UFixed18Lib.from( - Fixed18Lib.from(_versions[version].totalAssets) - .add(longAccumulated) - .add(shortAccumulated) - .max(Fixed18Lib.ZERO) // vault can't have negative assets, socializes into unclaimed if triggered - ); - } - - /** - * @notice The total shares at the given version - * @param version Version to get total shares at - * @return Total shares at `version` - */ - function _sharesAt(uint256 version) private view returns (UFixed18) { - return _versions[version].totalShares; - } - - /** - * @notice Converts a given amount of assets to shares at version - * @param context Version context to use in calculation - * @param assets Number of assets to convert to shares - * @return Amount of shares for the given assets at version - */ - function _convertToSharesAtVersion(VersionContext memory context, UFixed18 assets) private pure returns (UFixed18) { - if (context.latestCollateral.isZero()) return assets; - return assets.muldiv(context.latestShares, context.latestCollateral); - } - - /** - * @notice Converts a given amount of shares to assets at version - * @param context Version context to use in calculation - * @param shares Number of shares to convert to shares - * @return Amount of assets for the given shares at version - */ - function _convertToAssetsAtVersion(VersionContext memory context, UFixed18 shares) private pure returns (UFixed18) { - if (context.latestShares.isZero()) return shares; - return shares.muldiv(context.latestCollateral, context.latestShares); - } -} diff --git a/packages/perennial-vaults/contracts/balanced/BalancedVault.sol b/packages/perennial-vaults/contracts/balanced/BalancedVault.sol new file mode 100644 index 00000000..0b4492e3 --- /dev/null +++ b/packages/perennial-vaults/contracts/balanced/BalancedVault.sol @@ -0,0 +1,808 @@ +//SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.17; + +import "../interfaces/IBalancedVault.sol"; +import "@equilibria/root/control/unstructured/UInitializable.sol"; +import "@openzeppelin/contracts/utils/math/Math.sol"; +import "./BalancedVaultDefinition.sol"; + +/** + * @title BalancedVault + * @notice ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial. + * @dev Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to + * maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap + * the maximum amount of assets in the vault. + * + * The vault has a "delayed mint" mechanism for shares on deposit. After depositing to the vault, a user must wait + * until the next settlement of the underlying products in order for shares to be reflected in the getters. + * The shares will be fully reflected in contract state when the next settlement occurs on the vault itself. + * Similarly, when redeeming shares, underlying assets are not claimable until a settlement occurs. + * Each state changing interaction triggers the `settle` flywheel in order to bring the vault to the + * desired state. + * In the event that there is not a settlement for a long period of time, keepers can call the `sync` method to + * force settlement and rebalancing. This is most useful to prevent vault liquidation due to PnL changes + * causing the vault to be in an unhealthy state (far away from target leverage) + * + * This implementation is designed to be upgrade-compatible with instances of the previous single-payoff + * BalancedVault, here: https://github.com/equilibria-xyz/perennial-mono/blob/d970debe95e41598228e8c4ae52fb816797820fb/packages/perennial-vaults/contracts/BalancedVault.sol. + */ +contract BalancedVault is IBalancedVault, BalancedVaultDefinition, UInitializable { + UFixed18 constant private TWO = UFixed18.wrap(2e18); + + /// @dev The name of the vault + string public name; + + /// @dev Deprecated storage variable. Formerly `symbol` + string private __unused0; + + /// @dev Mapping of allowance across all users + mapping(address => mapping(address => UFixed18)) public allowance; + + /// @dev Mapping of shares of the vault per user + mapping(address => UFixed18) private _balanceOf; + + /// @dev Total number of shares across all users + UFixed18 private _totalSupply; + + /// @dev Mapping of unclaimed underlying of the vault per user + mapping(address => UFixed18) private _unclaimed; + + /// @dev Total unclaimed underlying of the vault across all users + UFixed18 private _totalUnclaimed; + + /// @dev Deposits that have not been settled, or have been settled but not yet processed by this contract + UFixed18 private _deposit; + + /// @dev Redemptions that have not been settled, or have been settled but not yet processed by this contract + UFixed18 private _redemption; + + /// @dev The latest epoch that a pending deposit or redemption has been placed + uint256 private _latestEpoch; + + /// @dev Mapping of pending (not yet converted to shares) per user + mapping(address => UFixed18) private _deposits; + + /// @dev Mapping of pending (not yet withdrawn) per user + mapping(address => UFixed18) private _redemptions; + + /// @dev Mapping of the latest epoch that a pending deposit or redemption has been placed per user + mapping(address => uint256) private _latestEpochs; + + /// @dev Per-asset accounting state variables (reserve space for maximum 50 assets due to storage pattern) + MarketAccount[50] private _marketAccounts; + + /// @dev Deposits that are queued for the following epoch due to the current epoch being stale + UFixed18 private _pendingDeposit; + + /// @dev Redemptions that are queued for the following epoch due to the current epoch being stale + UFixed18 private _pendingRedemption; + + /// @dev Mapping of queued deposits (due to stale epoch) per user + mapping(address => UFixed18) private _pendingDeposits; + + /// @dev Mapping of queued redemptions (due to stale epoch) per user + mapping(address => UFixed18) private _pendingRedemptions; + + /// @dev Mapping of the latest epoch for any queued deposit / redemption per user + mapping(address => uint256) private _pendingEpochs; + + constructor( + Token18 asset_, + IController controller_, + UFixed18 targetLeverage_, + UFixed18 maxCollateral_, + MarketDefinition[] memory marketDefinitions_ + ) + BalancedVaultDefinition(asset_, controller_, targetLeverage_, maxCollateral_, marketDefinitions_) + { } + + /** + * @notice Initializes the contract state + * @param name_ ERC20 asset name + */ + function initialize(string memory name_) external initializer(2) { + name = name_; // allow `name` to be reset + __unused0 = ""; // deprecate `symbol` + + // set or reset allowance compliant with both an initial deployment or an upgrade + asset.approve(address(collateral), UFixed18Lib.ZERO); + asset.approve(address(collateral)); + + // Stamp new market's data for first epoch + (EpochContext memory context, ) = _settle(address(0)); + for (uint256 marketId = 1; marketId < totalMarkets; marketId++) { + if (_marketAccounts[marketId].versionOf[context.epoch] == 0) { + _marketAccounts[marketId].versionOf[context.epoch] = markets(marketId).long.latestVersion(); + } + } + } + + /** + * @notice Rebalances the collateral and position of the vault without a deposit or withdraw + * @dev Should be called by a keeper when a new epoch is available, and there are pending deposits / redemptions + */ + function sync() external { + syncAccount(address(0)); + } + + /** + * @notice Syncs `account`'s state up to current + * @dev Also rebalances the collateral and position of the vault without a deposit or withdraw + * @param account The account that should be synced + */ + function syncAccount(address account) public { + (EpochContext memory context, ) = _settle(account); + _rebalance(context, UFixed18Lib.ZERO); + } + + /** + * @notice Deposits `assets` assets into the vault, returning shares to `account` after the deposit settles. + * @param assets The amount of assets to deposit + * @param account The account to deposit on behalf of + */ + function deposit(UFixed18 assets, address account) external { + (EpochContext memory context, ) = _settle(account); + if (assets.gt(_maxDepositAtEpoch(context))) revert BalancedVaultDepositLimitExceeded(); + + if (currentEpochStale()) { + _pendingDeposit = _pendingDeposit.add(assets); + _pendingDeposits[account] = _pendingDeposits[account].add(assets); + _pendingEpochs[account] = context.epoch + 1; + emit Deposit(msg.sender, account, context.epoch + 1, assets); + } else { + _deposit = _deposit.add(assets); + _deposits[account] = _deposits[account].add(assets); + _latestEpochs[account] = context.epoch; + emit Deposit(msg.sender, account, context.epoch, assets); + } + + asset.pull(msg.sender, assets); + + _rebalance(context, UFixed18Lib.ZERO); + } + + /** + * @notice Redeems `shares` shares from the vault + * @dev Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets + * If account is not msg.sender, requires prior spending approval + * @param shares The amount of shares to redeem + * @param account The account to redeem on behalf of + */ + function redeem(UFixed18 shares, address account) external { + if (msg.sender != account) _consumeAllowance(account, msg.sender, shares); + + (EpochContext memory context, EpochContext memory accountContext) = _settle(account); + if (shares.gt(_maxRedeemAtEpoch(context, accountContext, account))) revert BalancedVaultRedemptionLimitExceeded(); + + if (currentEpochStale()) { + _pendingRedemption = _pendingRedemption.add(shares); + _pendingRedemptions[account] = _pendingRedemptions[account].add(shares); + _pendingEpochs[account] = context.epoch + 1; + emit Redemption(msg.sender, account, context.epoch + 1, shares); + } else { + _redemption = _redemption.add(shares); + _redemptions[account] = _redemptions[account].add(shares); + _latestEpochs[account] = context.epoch; + emit Redemption(msg.sender, account, context.epoch, shares); + } + + _burn(account, shares); + + _rebalance(context, UFixed18Lib.ZERO); + } + + /** + * @notice Claims all claimable assets for account, sending assets to account + * @param account The account to claim for + */ + function claim(address account) external { + (EpochContext memory context, ) = _settle(account); + + UFixed18 unclaimedAmount = _unclaimed[account]; + UFixed18 unclaimedTotal = _totalUnclaimed; + _unclaimed[account] = UFixed18Lib.ZERO; + _totalUnclaimed = unclaimedTotal.sub(unclaimedAmount); + emit Claim(msg.sender, account, unclaimedAmount); + + // pro-rate if vault has less collateral than unclaimed + UFixed18 claimAmount = unclaimedAmount; + UFixed18 totalCollateral = _assets(); + if (totalCollateral.lt(unclaimedTotal)) claimAmount = claimAmount.muldiv(totalCollateral, unclaimedTotal); + + _rebalance(context, claimAmount); + + asset.push(account, claimAmount); + } + + /** + * @notice Sets `amount` as the allowance of `spender` over the caller's shares + * @param spender Address which can spend operate on shares + * @param amount Amount of shares that spender can operate on + * @return bool true if the approval was successful, otherwise reverts + */ + function approve(address spender, UFixed18 amount) external returns (bool) { + allowance[msg.sender][spender] = amount; + emit Approval(msg.sender, spender, amount); + return true; + } + + /** + * @notice The maximum available deposit amount + * @dev Only exact when vault is synced, otherwise approximate + * @return Maximum available deposit amount + */ + function maxDeposit(address) external view returns (UFixed18) { + (EpochContext memory context, ) = _loadContextForRead(address(0)); + return _maxDepositAtEpoch(context); + } + + /** + * @notice The maximum available redeemable amount + * @dev Only exact when vault is synced, otherwise approximate + * @param account The account to redeem for + * @return Maximum available redeemable amount + */ + function maxRedeem(address account) external view returns (UFixed18) { + (EpochContext memory context, EpochContext memory accountContext) = _loadContextForRead(account); + return _maxRedeemAtEpoch(context, accountContext, account); + } + + /** + * @notice The total amount of assets currently held by the vault + * @return Amount of assets held by the vault + */ + function totalAssets() external view returns (UFixed18) { + (EpochContext memory context, ) = _loadContextForRead(address(0)); + return _totalAssetsAtEpoch(context); + } + + /** + * @notice The total amount of shares currently issued + * @return Amount of shares currently issued + */ + function totalSupply() external view returns (UFixed18) { + (EpochContext memory context, ) = _loadContextForRead(address(0)); + return _totalSupplyAtEpoch(context); + } + + /** + * @notice Number of shares held by `account` + * @param account Account to query balance of + * @return Number of shares held by `account` + */ + function balanceOf(address account) external view returns (UFixed18) { + (, EpochContext memory accountContext) = _loadContextForRead(account); + return _balanceOfAtEpoch(accountContext, account); + } + + /** + * @notice Total unclaimed assets in vault + * @return Total unclaimed assets in vault + */ + function totalUnclaimed() external view returns (UFixed18) { + (EpochContext memory context, ) = _loadContextForRead(address(0)); + return _totalUnclaimedAtEpoch(context); + } + + /** + * @notice `account`'s unclaimed assets + * @param account Account to query unclaimed balance of + * @return `account`'s unclaimed assets + */ + function unclaimed(address account) external view returns (UFixed18) { + (, EpochContext memory accountContext) = _loadContextForRead(account); + return _unclaimedAtEpoch(accountContext, account); + } + + /** + * @notice Converts a given amount of assets to shares + * @param assets Number of assets to convert to shares + * @return Amount of shares for the given assets + */ + function convertToShares(UFixed18 assets) external view returns (UFixed18) { + (EpochContext memory context, ) = _loadContextForRead(address(0)); + (context.latestAssets, context.latestShares) = + (_totalAssetsAtEpoch(context), _totalSupplyAtEpoch(context)); + return _convertToSharesAtEpoch(context, assets); + } + + /** + * @notice Converts a given amount of shares to assets + * @param shares Number of shares to convert to assets + * @return Amount of assets for the given shares + */ + function convertToAssets(UFixed18 shares) external view returns (UFixed18) { + (EpochContext memory context, ) = _loadContextForRead(address(0)); + (context.latestAssets, context.latestShares) = + (_totalAssetsAtEpoch(context), _totalSupplyAtEpoch(context)); + return _convertToAssetsAtEpoch(context, shares); + } + + /** + * @notice Returns the current epoch + * @return The current epoch + */ + function currentEpoch() public view returns (uint256) { + return currentEpochComplete() ? _latestEpoch + 1 : _latestEpoch; + } + + /** + * @notice Returns the whether the current epoch is currently complete + * @dev An epoch is "complete" when all of the underlying oracles have advanced a version + * @return Whether the current epoch is complete + */ + function currentEpochComplete() public view returns (bool) { + for (uint256 marketId; marketId < totalMarkets; marketId++) { + if ( + Math.min(markets(marketId).long.latestVersion(), markets(marketId).short.latestVersion()) == + _versionAtEpoch(marketId, _latestEpoch) + ) return false; + } + return true; + } + + /** + * @notice Returns the whether the current epoch is currently stale + * @dev An epoch is "stale" when any one of the underlying oracles have advanced a version + * @return Whether the current epoch is stale + */ + function currentEpochStale() public view returns (bool) { + for (uint256 marketId; marketId < totalMarkets; marketId++) { + if ( + Math.max(markets(marketId).long.latestVersion(), markets(marketId).short.latestVersion()) > + _versionAtEpoch(marketId, _latestEpoch) + ) return true; + } + return false; + } + + /** + * @notice Hook that is called before every stateful operation + * @dev Settles the vault's account on both the long and short product, along with any global or user-specific deposits/redemptions + * @param account The account that called the operation, or 0 if called by a keeper. + * @return context The current epoch contexts for each market + * @return accountContext The current epoch contexts for each market for the given account + */ + function _settle(address account) private returns (EpochContext memory context, EpochContext memory accountContext) { + (context, accountContext) = _loadContextForWrite(account); + + if (context.epoch > _latestEpoch) { + _delayedMint(_totalSupplyAtEpoch(context).sub(_totalSupply.add(_pendingRedemption))); + _totalUnclaimed = _totalUnclaimedAtEpoch(context); + _deposit = UFixed18Lib.ZERO; + _redemption = UFixed18Lib.ZERO; + _latestEpoch = context.epoch; + + for (uint256 marketId; marketId < totalMarkets; marketId++) { + MarketEpoch storage marketEpoch = _marketAccounts[marketId].epochs[context.epoch]; + + marketEpoch.longPosition = markets(marketId).long.position(address(this)).maker; + marketEpoch.shortPosition = markets(marketId).short.position(address(this)).maker; + marketEpoch.longAssets = collateral.collateral(address(this), markets(marketId).long); + marketEpoch.shortAssets = collateral.collateral(address(this), markets(marketId).short); + + _marketAccounts[marketId].versionOf[context.epoch] = markets(marketId).long.latestVersion(); + } + _marketAccounts[0].epochs[context.epoch].totalShares = _totalSupplyAtEpoch(context); + _marketAccounts[0].epochs[context.epoch].totalAssets = _totalAssetsAtEpoch(context); + + // process pending deposit / redemption after new epoch is settled + _deposit = _pendingDeposit; + _redemption = _pendingRedemption; + _pendingDeposit = UFixed18Lib.ZERO; + _pendingRedemption = UFixed18Lib.ZERO; + } + + if (account != address(0)) { + if (accountContext.epoch > _latestEpochs[account]) { + _delayedMintAccount(account, _balanceOfAtEpoch(accountContext, account).sub(_balanceOf[account].add(_pendingRedemptions[account]))); + _unclaimed[account] = _unclaimedAtEpoch(accountContext, account); + _deposits[account] = UFixed18Lib.ZERO; + _redemptions[account] = UFixed18Lib.ZERO; + _latestEpochs[account] = accountContext.epoch; + } + if (accountContext.epoch > _pendingEpochs[account]) { + _deposits[account] = _pendingDeposits[account]; + _redemptions[account] = _pendingRedemptions[account]; + _latestEpochs[account] = _pendingEpochs[account]; + _pendingDeposits[account] = UFixed18Lib.ZERO; + _pendingRedemptions[account] = UFixed18Lib.ZERO; + _pendingEpochs[account] = accountContext.epoch; + + (context, accountContext) = _settle(account); // run settle again after moving pending deposits and redemptions into current + } + } + } + + /** + * @notice Rebalances the collateral and position of the vault + * @dev Rebalance is executed on best-effort, any failing legs of the strategy will not cause a revert + * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation + */ + function _rebalance(EpochContext memory context, UFixed18 claimAmount) private { + _rebalanceCollateral(claimAmount); + _rebalancePosition(context, claimAmount); + } + + /** + * @notice Rebalances the collateral of the vault + * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation + */ + function _rebalanceCollateral(UFixed18 claimAmount) private { + // Compute target collateral + UFixed18 targetCollateral = _assets().sub(claimAmount).div(TWO); + if (targetCollateral.muldiv(minWeight, totalWeight).lt(controller.minCollateral())) + targetCollateral = UFixed18Lib.ZERO; + + // Remove collateral from markets above target + for (uint256 marketId; marketId < totalMarkets; marketId++) { + UFixed18 marketCollateral = targetCollateral.muldiv(markets(marketId).weight, totalWeight); + + if (collateral.collateral(address(this), markets(marketId).long).gt(marketCollateral)) + _updateCollateral(markets(marketId).long, marketCollateral); + if (collateral.collateral(address(this), markets(marketId).short).gt(marketCollateral)) + _updateCollateral(markets(marketId).short, marketCollateral); + } + + // Deposit collateral to markets below target + for (uint256 marketId; marketId < totalMarkets; marketId++) { + UFixed18 marketCollateral = targetCollateral.muldiv(markets(marketId).weight, totalWeight); + + if (collateral.collateral(address(this), markets(marketId).long).lt(marketCollateral)) + _updateCollateral(markets(marketId).long, marketCollateral); + if (collateral.collateral(address(this), markets(marketId).short).lt(marketCollateral)) + _updateCollateral(markets(marketId).short, marketCollateral); + } + } + + /** + * @notice Rebalances the position of the vault + * @param context Epoch context to use in calculation + * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation + */ + function _rebalancePosition(EpochContext memory context, UFixed18 claimAmount) private { + // Compute target collateral + UFixed18 targetCollateral = _totalAssetsAtEpoch(context).sub(claimAmount) + .mul(_totalSupplyAtEpoch(context).unsafeDiv(_totalSupplyAtEpoch(context).add(_redemption))) + .add(_deposit) + .div(TWO); + if (targetCollateral.muldiv(minWeight, totalWeight).lt(controller.minCollateral())) + targetCollateral = UFixed18Lib.ZERO; + + // Target new maker position per market price and weight + for (uint256 marketId; marketId < totalMarkets; marketId++) { + UFixed18 marketCollateral = targetCollateral.muldiv(markets(marketId).weight, totalWeight); + if (markets(marketId).long.closed() || markets(marketId).short.closed()) marketCollateral = UFixed18Lib.ZERO; + + uint256 version = _versionAtEpoch(marketId, context.epoch); + UFixed18 currentPrice = markets(marketId).long.atVersion(version).price.abs(); + UFixed18 targetPosition = marketCollateral.mul(targetLeverage).div(currentPrice); + + _updateMakerPosition(markets(marketId).long, targetPosition); + _updateMakerPosition(markets(marketId).short, targetPosition); + } + } + + /** + * @notice Adjusts the position on `product` to `targetPosition` + * @param product The product to adjust the vault's position on + * @param targetPosition The new position to target + */ + function _updateMakerPosition(IProduct product, UFixed18 targetPosition) private { + UFixed18 accountPosition = product.position(address(this)).next(product.pre(address(this))).maker; + + if (targetPosition.lt(accountPosition)) { + // compute headroom until hitting taker amount + Position memory position = product.positionAtVersion(product.latestVersion()).next(product.pre()); + UFixed18 makerAvailable = position.maker.gt(position.taker) ? + position.maker.sub(position.taker) : + UFixed18Lib.ZERO; + + product.closeMake(accountPosition.sub(targetPosition).min(makerAvailable)); + } + + if (targetPosition.gt(accountPosition)) { + // compute headroom until hitting makerLimit + UFixed18 currentMaker = product.positionAtVersion(product.latestVersion()).next(product.pre()).maker; + UFixed18 makerLimit = product.makerLimit(); + UFixed18 makerAvailable = makerLimit.gt(currentMaker) ? makerLimit.sub(currentMaker) : UFixed18Lib.ZERO; + + product.openMake(targetPosition.sub(accountPosition).min(makerAvailable)); + } + } + + /** + * @notice Adjusts the collateral on `product` to `targetCollateral` + * @param product The product to adjust the vault's collateral on + * @param targetCollateral The new collateral to target + */ + function _updateCollateral(IProduct product, UFixed18 targetCollateral) private { + UFixed18 currentCollateral = collateral.collateral(address(this), product); + + if (currentCollateral.gt(targetCollateral)) + collateral.withdrawTo(address(this), product, currentCollateral.sub(targetCollateral)); + if (currentCollateral.lt(targetCollateral)) + collateral.depositTo(address(this), product, targetCollateral.sub(currentCollateral)); + } + + /** + * @notice Burns `amount` shares from `from`, adjusting totalSupply + * @param from Address to burn shares from + * @param amount Amount of shares to burn + */ + function _burn(address from, UFixed18 amount) private { + _balanceOf[from] = _balanceOf[from].sub(amount); + _totalSupply = _totalSupply.sub(amount); + emit Burn(from, amount); + } + + /** + * @notice Mints `amount` shares, adjusting totalSupply + * @param amount Amount of shares to mint + */ + function _delayedMint(UFixed18 amount) private { + _totalSupply = _totalSupply.add(amount); + } + + /** + * @notice Mints `amount` shares to `to` + * @param to Address to mint shares to + * @param amount Amount of shares to mint + */ + function _delayedMintAccount(address to, UFixed18 amount) private { + _balanceOf[to] = _balanceOf[to].add(amount); + emit Mint(to, amount); + } + + /** + * @notice Decrements `spender`s allowance for `account` by `amount` + * @dev Does not decrement if approval is for -1 + * @param account Address of allower + * @param spender Address of spender + * @param amount Amount to decrease allowance by + */ + function _consumeAllowance(address account, address spender, UFixed18 amount) private { + if (allowance[account][spender].eq(UFixed18Lib.MAX)) return; + allowance[account][spender] = allowance[account][spender].sub(amount); + } + + /** + * @notice Loads the context for the given `account`, settling the vault first + * @param account Account to load the context for + * @return global epoch context + * @return account epoch context + */ + function _loadContextForWrite(address account) private returns (EpochContext memory, EpochContext memory) { + for (uint256 marketId; marketId < totalMarkets; marketId++) { + markets(marketId).long.settleAccount(address(this)); + markets(marketId).short.settleAccount(address(this)); + } + + return _loadContextForRead(account); + } + + /** + * @notice Loads the context for the given `account` + * @param account Account to load the context for + * @return global epoch context + * @return account epoch context + */ + function _loadContextForRead(address account) private view returns (EpochContext memory, EpochContext memory) { + uint256 _currentEpoch = currentEpoch(); + return ( + EpochContext(_currentEpoch, _assetsAtEpoch(_latestEpoch), _sharesAtEpoch(_latestEpoch)), + EpochContext(_currentEpoch, _assetsAtEpoch(_latestEpochs[account]), _sharesAtEpoch(_latestEpochs[account])) + ); + } + + /** + * @notice Calculates whether or not the vault is in an unhealthy state at the provided epoch + * @param context Epoch context to calculate health + * @return bool true if unhealthy, false if healthy + */ + function _unhealthyAtEpoch(EpochContext memory context) private view returns (bool) { + if (!context.latestShares.isZero() && context.latestAssets.isZero()) return true; + for (uint256 marketId; marketId < totalMarkets; marketId++) { + if (_unhealthy(markets(marketId))) return true; + } + return false; + } + + /** + * @notice Determines whether the market pair is currently in an unhealthy state + * @dev market is unhealthy if either the long or short markets are liquidating or liquidatable + * @param marketDefinition The configuration of the market + * @return bool true if unhealthy, false if healthy + */ + function _unhealthy(MarketDefinition memory marketDefinition) internal view returns (bool) { + return collateral.liquidatable(address(this), marketDefinition.long) + || collateral.liquidatable(address(this), marketDefinition.short) + || marketDefinition.long.isLiquidating(address(this)) + || marketDefinition.short.isLiquidating(address(this)); + } + + /** + * @notice The maximum available deposit amount at the given epoch + * @param context Epoch context to use in calculation + * @return Maximum available deposit amount at epoch + */ + function _maxDepositAtEpoch(EpochContext memory context) private view returns (UFixed18) { + if (_unhealthyAtEpoch(context)) return UFixed18Lib.ZERO; + UFixed18 currentCollateral = _totalAssetsAtEpoch(context).add(_deposit).add(_pendingDeposit); + return maxCollateral.gt(currentCollateral) ? maxCollateral.sub(currentCollateral) : UFixed18Lib.ZERO; + } + + /** + * @notice The maximum available redeemable amount at the given epoch for `account` + * @param context Epoch context to use in calculation + * @param accountContext Account epoch context to use in calculation + * @param account Account to calculate redeemable amount + * @return Maximum available redeemable amount at epoch + */ + function _maxRedeemAtEpoch( + EpochContext memory context, + EpochContext memory accountContext, + address account + ) private view returns (UFixed18) { + if (_unhealthyAtEpoch(context)) return UFixed18Lib.ZERO; + return _balanceOfAtEpoch(accountContext, account); + } + + /** + * @notice The total assets at the given epoch + * @param context Epoch context to use in calculation + * @return Total assets amount at epoch + */ + function _totalAssetsAtEpoch(EpochContext memory context) private view returns (UFixed18) { + (UFixed18 totalCollateral, UFixed18 totalDebt) = ( + _assets(), + _totalUnclaimedAtEpoch(context).add(_deposit).add(_pendingDeposit) + ); + return totalCollateral.gt(totalDebt) ? totalCollateral.sub(totalDebt) : UFixed18Lib.ZERO; + } + + /** + * @notice The total supply at the given epoch + * @param context Epoch context to use in calculation + * @return Total supply amount at epoch + */ + function _totalSupplyAtEpoch(EpochContext memory context) private view returns (UFixed18) { + if (context.epoch == _latestEpoch) return _totalSupply.add(_pendingRedemption); + return _totalSupply.add(_pendingRedemption).add(_convertToSharesAtEpoch(context, _deposit)); + } + + /** + * @notice The balance of `account` at the given epoch + * @param accountContext Account epoch context to use in calculation + * @param account Account to calculate balance of amount + * @return Account balance at epoch + */ + function _balanceOfAtEpoch(EpochContext memory accountContext, address account) private view returns (UFixed18) { + if (accountContext.epoch == _latestEpochs[account]) return _balanceOf[account].add(_pendingRedemptions[account]); + return _balanceOf[account].add(_pendingRedemptions[account]).add(_convertToSharesAtEpoch(accountContext, _deposits[account])); + } + + /** + * @notice The total unclaimed assets at the given epoch + * @param context Epoch context to use in calculation + * @return Total unclaimed asset amount at epoch + */ + function _totalUnclaimedAtEpoch(EpochContext memory context) private view returns (UFixed18) { + if (context.epoch == _latestEpoch) return _totalUnclaimed; + return _totalUnclaimed.add(_convertToAssetsAtEpoch(context, _redemption)); + } + + /** + * @notice The total unclaimed assets at the given epoch for `account` + * @param accountContext Account epoch context to use in calculation + * @param account Account to calculate unclaimed assets for + * @return Total unclaimed asset amount for `account` at epoch + */ + function _unclaimedAtEpoch(EpochContext memory accountContext, address account) private view returns (UFixed18) { + if (accountContext.epoch == _latestEpochs[account]) return _unclaimed[account]; + return _unclaimed[account].add(_convertToAssetsAtEpoch(accountContext, _redemptions[account])); + } + + /** + * @notice Returns the amounts of the individual sources of assets in the vault + * @return value The real amount of collateral in the vault + **/ + function _assets() public view returns (UFixed18 value) { + value = asset.balanceOf(); + for (uint256 marketId; marketId < totalMarkets; marketId++) { + value = value + .add(collateral.collateral(address(this), markets(marketId).long)) + .add(collateral.collateral(address(this), markets(marketId).short)); + } + } + + /** + * @notice Converts a given amount of assets to shares at epoch + * @param context Epoch context to use in calculation + * @param assets Number of assets to convert to shares + * @return Amount of shares for the given assets at epoch + */ + function _convertToSharesAtEpoch(EpochContext memory context, UFixed18 assets) private pure returns (UFixed18) { + if (context.latestAssets.isZero()) return assets; + return assets.muldiv(context.latestShares, context.latestAssets); + } + + /** + * @notice Converts a given amount of shares to assets at epoch + * @param context Epoch context to use in calculation + * @param shares Number of shares to convert to shares + * @return Amount of assets for the given shares at epoch + */ + function _convertToAssetsAtEpoch(EpochContext memory context, UFixed18 shares) private pure returns (UFixed18) { + if (context.latestShares.isZero()) return shares; + return shares.muldiv(context.latestAssets, context.latestShares); + } + + /** + * @notice The total assets at the given epoch + * @dev Calculates and adds accumulated PnL for `version` + 1 + * @param epoch Epoch to get total assets at + * @return assets Total assets in the vault at the given epoch + */ + function _assetsAtEpoch(uint256 epoch) private view returns (UFixed18) { + Fixed18 assets = Fixed18Lib.from(_marketAccounts[0].epochs[epoch].totalAssets); + for (uint256 marketId; marketId < totalMarkets; marketId++) { + assets = assets.add(_accumulatedAtEpoch(marketId, epoch)); + } + + // collateral can't go negative within the vault, socializes into unclaimed if triggered + return UFixed18Lib.from(assets.max(Fixed18Lib.ZERO)); + } + + /** + * @notice The total shares at the given epoch + * @param epoch Epoch to get total shares at + * @return Total shares at `epoch` + */ + function _sharesAtEpoch(uint256 epoch) private view returns (UFixed18) { + return _marketAccounts[0].epochs[epoch].totalShares; + } + + /** + * @notice The total assets accumulated at the given epoch for a market pair + * @dev Calculates accumulated PnL for `version` to `version + 1` + * @param marketId The market ID to accumulate for + * @param epoch Epoch to get total assets at + * @return Total assets accumulated + */ + function _accumulatedAtEpoch(uint256 marketId, uint256 epoch) private view returns (Fixed18) { + MarketEpoch memory marketEpoch = _marketAccounts[marketId].epochs[epoch]; + uint256 version = _versionAtEpoch(marketId, epoch); + + // accumulate value from version n + 1 + (Fixed18 longAccumulated, Fixed18 shortAccumulated) = ( + markets(marketId).long.valueAtVersion(version + 1).maker + .sub(markets(marketId).long.valueAtVersion(version).maker) + .mul(Fixed18Lib.from(marketEpoch.longPosition)), + markets(marketId).short.valueAtVersion(version + 1).maker + .sub(markets(marketId).short.valueAtVersion(version).maker) + .mul(Fixed18Lib.from(marketEpoch.shortPosition)) + ); + + // collateral can't go negative on a product + longAccumulated = longAccumulated.max(Fixed18Lib.from(marketEpoch.longAssets).mul(Fixed18Lib.NEG_ONE)); + shortAccumulated = shortAccumulated.max(Fixed18Lib.from(marketEpoch.shortAssets).mul(Fixed18Lib.NEG_ONE)); + + return longAccumulated.add(shortAccumulated); + } + + /** + * @notice Finds the version of a market and a specific epoch + * @dev This latest implementation of the BalanceVault introduces the concept of "epochs" to enable + * multi-payoff vaults. In order to maintain upgrade compatibility with previous version-based instances, + * we maintain the invariant that version == epoch prior to the upgrade switchover. + * @param marketId The market ID to accumulate for + * @param epoch Epoch to get total assets at + * @return The version at epoch + */ + function _versionAtEpoch(uint256 marketId, uint256 epoch) private view returns (uint256) { + if (epoch > _latestEpoch) return 0; + uint256 version = _marketAccounts[marketId].versionOf[epoch]; + return (version == 0) ? epoch : version; + } +} diff --git a/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol b/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol new file mode 100644 index 00000000..7c247323 --- /dev/null +++ b/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol @@ -0,0 +1,110 @@ +//SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.17; + +import "../interfaces/IBalancedVaultDefinition.sol"; + +/** + * @title BalancedVault + * @notice ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial. + * @dev Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to + * maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap + * the maximum amount of assets in the vault. + * + * The vault has a "delayed mint" mechanism for shares on deposit. After depositing to the vault, a user must wait + * until the next settlement of the underlying products in order for shares to be reflected in the getters. + * The shares will be fully reflected in contract state when the next settlement occurs on the vault itself. + * Similarly, when redeeming shares, underlying assets are not claimable until a settlement occurs. + * Each state changing interaction triggers the `settle` flywheel in order to bring the vault to the + * desired state. + * In the event that there is not a settlement for a long period of time, keepers can call the `sync` method to + * force settlement and rebalancing. This is most useful to prevent vault liquidation due to PnL changes + * causing the vault to be in an unhealthy state (far away from target leverage) + */ +contract BalancedVaultDefinition is IBalancedVaultDefinition { + IProduct private constant DEFAULT_PRODUCT = IProduct(address(0)); + uint256 private constant DEFAULT_WEIGHT = 0; + uint256 private constant MAX_MARKETS = 2; + + /// @dev The address of the Perennial controller contract + IController public immutable controller; + + /// @dev The address of the Perennial collateral contract + ICollateral public immutable collateral; + + /// @dev The target leverage amount for the vault + UFixed18 public immutable targetLeverage; + + /// @dev The collateral cap for the vault + UFixed18 public immutable maxCollateral; + + /// @dev The underlying asset of the vault + Token18 public immutable asset; + + /// @dev The number of markets in the vault + uint256 public immutable totalMarkets; + + /// @dev The sum of the weights of all products in the vault + uint256 public immutable totalWeight; + + /// @dev The minimum of the weights of all products in the vault + uint256 public immutable minWeight; + + /// @dev The product corresponding to the long of each payoff + IProduct private immutable long0; + IProduct private immutable long1; + + /// @dev The product corresponding to the short of each payoff + IProduct private immutable short0; + IProduct private immutable short1; + + /// @dev The the weight of each given payoff in the vault + uint256 private immutable weight0; + uint256 private immutable weight1; + + constructor( + Token18 asset_, + IController controller_, + UFixed18 targetLeverage_, + UFixed18 maxCollateral_, + MarketDefinition[] memory marketDefinitions_ + ) { + asset = asset_; + controller = controller_; + collateral = controller_.collateral(); + targetLeverage = targetLeverage_; + maxCollateral = maxCollateral_; + + uint256 totalMarkets_ = Math.min(marketDefinitions_.length, MAX_MARKETS); + uint256 totalWeight_; + uint256 minWeight_ = type(uint256).max; + + long0 = (totalMarkets_ > 0) ? marketDefinitions_[0].long : DEFAULT_PRODUCT; + short0 = (totalMarkets_ > 0) ? marketDefinitions_[0].short : DEFAULT_PRODUCT; + weight0 = (totalMarkets_ > 0) ? marketDefinitions_[0].weight : DEFAULT_WEIGHT; + + long1 = (totalMarkets_ > 1) ? marketDefinitions_[1].long : DEFAULT_PRODUCT; + short1 = (totalMarkets_ > 1) ? marketDefinitions_[1].short : DEFAULT_PRODUCT; + weight1 = (totalMarkets_ > 1) ? marketDefinitions_[1].weight : DEFAULT_WEIGHT; + + for (uint256 marketId; marketId < totalMarkets_; marketId++) { + totalWeight_ += marketDefinitions_[marketId].weight; + if (minWeight_ > marketDefinitions_[marketId].weight) minWeight_ = marketDefinitions_[marketId].weight; + } + + totalMarkets = totalMarkets_; + totalWeight = totalWeight_; + minWeight = minWeight_; + } + + /** + * @notice Returns the market definition for a market + * @param marketId The market ID to get products for + * @return market The market definition + */ + function markets(uint256 marketId) public view returns (MarketDefinition memory market) { + if (totalMarkets > 0 && marketId == 0) return MarketDefinition(long0, short0, weight0); + if (totalMarkets > 1 && marketId == 1) return MarketDefinition(long1, short1, weight1); + + revert BalancedVaultDefinitionInvalidMarketIdError(); + } +} diff --git a/packages/perennial-vaults/contracts/interfaces/IBalancedVault.sol b/packages/perennial-vaults/contracts/interfaces/IBalancedVault.sol index 01e35849..ba926cf9 100644 --- a/packages/perennial-vaults/contracts/interfaces/IBalancedVault.sol +++ b/packages/perennial-vaults/contracts/interfaces/IBalancedVault.sol @@ -4,50 +4,53 @@ pragma solidity ^0.8.13; import "@equilibria/perennial/contracts/interfaces/IController.sol"; import "@equilibria/perennial/contracts/interfaces/ICollateral.sol"; import "@equilibria/root/number/types/UFixed18.sol"; +import "./IBalancedVaultDefinition.sol"; -interface IBalancedVault { +interface IBalancedVault is IBalancedVaultDefinition { - /* BalancedVault Interface */ + struct EpochContext { + uint256 epoch; + UFixed18 latestAssets; + UFixed18 latestShares; + } - struct Version { + struct MarketEpoch { UFixed18 longPosition; UFixed18 shortPosition; - UFixed18 totalShares; + UFixed18 totalShares; // @dev: index-0 is used globally for compatibility with previous implementation UFixed18 longAssets; UFixed18 shortAssets; - UFixed18 totalAssets; + UFixed18 totalAssets; // @dev: index-0 is used globally for compatibility with previous implementation } - struct VersionContext { - uint256 version; - UFixed18 latestCollateral; - UFixed18 latestShares; + struct MarketAccount { + mapping(uint256 => MarketEpoch) epochs; + mapping(uint256 => uint256) versionOf; + uint256[50] __reserved__; } + event Mint(address indexed account, UFixed18 amount); + event Burn(address indexed account, UFixed18 amount); event Deposit(address indexed sender, address indexed account, uint256 version, UFixed18 assets); event Redemption(address indexed sender, address indexed account, uint256 version, UFixed18 shares); event Claim(address indexed sender, address indexed account, UFixed18 assets); - event PositionUpdated(IProduct product, UFixed18 targetPosition); - event CollateralUpdated(IProduct product, UFixed18 targetCollateral); error BalancedVaultDepositLimitExceeded(); error BalancedVaultRedemptionLimitExceeded(); - function initialize(string memory name_, string memory symbol_) external; + function name() external view returns (string memory); + function initialize(string memory name_) external; function sync() external; - function controller() external view returns (IController); - function collateral() external view returns (ICollateral); - function long() external view returns (IProduct); - function short() external view returns (IProduct); - function targetLeverage() external view returns (UFixed18); - function maxCollateral() external view returns (UFixed18); + function syncAccount(address account) external; function unclaimed(address account) external view returns (UFixed18); function totalUnclaimed() external view returns (UFixed18); function claim(address account) external; + function currentEpoch() external view returns (uint256); + function currentEpochStale() external view returns (bool); + function currentEpochComplete() external view returns (bool); /* Partial ERC4626 Interface */ - function asset() external view returns (Token18); function totalAssets() external view returns (UFixed18); function convertToShares(UFixed18 assets) external view returns (UFixed18); function convertToAssets(UFixed18 shares) external view returns (UFixed18); @@ -58,16 +61,10 @@ interface IBalancedVault { /* Partial ERC20 Interface */ - event Transfer(address indexed from, address indexed to, UFixed18 value); - event Approval(address indexed account, address indexed spender, UFixed18 value); + event Approval(address indexed account, address indexed spender, UFixed18 amount); - function name() external view returns (string memory); - function symbol() external view returns (string memory); - function decimals() external view returns (uint8); function totalSupply() external view returns (UFixed18); function balanceOf(address account) external view returns (UFixed18); - function transfer(address to, UFixed18 amount) external returns (bool); function allowance(address account, address spender) external view returns (UFixed18); function approve(address spender, UFixed18 amount) external returns (bool); - function transferFrom(address from, address to, UFixed18 amount) external returns (bool); } diff --git a/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol b/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol new file mode 100644 index 00000000..ae58b12f --- /dev/null +++ b/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol @@ -0,0 +1,24 @@ +//SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.13; + +import "@equilibria/perennial/contracts/interfaces/IProduct.sol"; +import "@equilibria/perennial/contracts/interfaces/IController.sol"; + +interface IBalancedVaultDefinition { + struct MarketDefinition { + IProduct long; + IProduct short; + uint256 weight; + } + + error BalancedVaultDefinitionInvalidMarketIdError(); + + function asset() external view returns (Token18); + function totalMarkets() external view returns (uint256); + function totalWeight() external view returns (uint256); + function controller() external view returns (IController); + function collateral() external view returns (ICollateral); + function targetLeverage() external view returns (UFixed18); + function maxCollateral() external view returns (UFixed18); + function markets(uint256 market) external view returns (MarketDefinition memory); +} diff --git a/packages/perennial-vaults/hardhat.config.ts b/packages/perennial-vaults/hardhat.config.ts index 9131561d..cadf2315 100644 --- a/packages/perennial-vaults/hardhat.config.ts +++ b/packages/perennial-vaults/hardhat.config.ts @@ -1,10 +1,46 @@ import { dirname } from 'path' -import defaultConfig, { FORK_ENABLED, FORK_NETWORK } from '../common/hardhat.default.config' +import defaultConfig, { OPTIMIZER_ENABLED, FORK_ENABLED, FORK_NETWORK } from '../common/hardhat.default.config' const eqPerennialDir = dirname(require.resolve('@equilibria/perennial/package.json')) +const MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES = { + version: '0.8.17', + settings: { + viaIR: true, + optimizer: { + enabled: true, + runs: 1, + details: { + yulDetails: { + // We checked with the Compound team to confirm that this should be safe to use to other projects + optimizerSteps: + 'dhfoDgvulfnTUtnIf [xa[r]scLM cCTUtTOntnfDIul Lcul Vcul [j] Tpeul xa[rul] xa[r]cL gvif CTUca[r]LsTOtfDnca[r]Iulc] jmul[jul] VcTOcul jmul', + }, + }, + }, + outputSelection: OPTIMIZER_ENABLED + ? { + '*': { + '*': ['evm.deployedBytecode.sourceMap'], + }, + } + : { + '*': { + '*': ['storageLayout'], // This is needed by Smock for mocking functions + }, + }, + }, +} + const config = defaultConfig({ - solidityVersion: '0.8.17', + solidityVersion: '0.8.15', + solidityOverrides: { + 'contracts/balanced/BalancedVault.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, + 'contracts/balanced/BalancedVaultDefinition.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, + 'contracts/balanced/types/MarketAccount.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, + 'contracts/balanced/types/MarketDefinition.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, + 'contracts/PerennialLib.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, + }, externalDeployments: { goerli: [`${eqPerennialDir}/deployments/goerli`, `${eqPerennialDir}/external/deployments/goerli`], mainnet: [`${eqPerennialDir}/deployments/mainnet`, `${eqPerennialDir}/external/deployments/mainnet`], @@ -22,6 +58,7 @@ const config = defaultConfig({ }, dependencyPaths: [ '@equilibria/perennial/contracts/interfaces/IController.sol', + '@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol', '@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol', ], }) diff --git a/packages/perennial-vaults/package.json b/packages/perennial-vaults/package.json index c956fe1d..58adc1ab 100644 --- a/packages/perennial-vaults/package.json +++ b/packages/perennial-vaults/package.json @@ -17,7 +17,7 @@ "verify": "hardhat etherscan-verify --sleep --solc-input", "gasReport": "REPORT_GAS=true yarn test:integration", "test": "hardhat test test/unit/**/*", - "test:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat test test/integration/*", + "test:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat test test/integration/**/*", "test:verification:arbitrum": "FORK_ENABLED=true FORK_NETWORK=arbitrum FORK_BLOCK_NUMBER=75050457 FORK_USE_REAL_DEPLOYS=true hardhat test test/verification/arbitrum/**/*", "coverage": "hardhat coverage --testfiles 'test/unit/**/*'", "coverage:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat coverage --testfiles 'test/integration/*'", diff --git a/packages/perennial-vaults/test/integration/balancedVault.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts similarity index 77% rename from packages/perennial-vaults/test/integration/balancedVault.test.ts rename to packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts index 43492d49..6fe951b5 100644 --- a/packages/perennial-vaults/test/integration/balancedVault.test.ts +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts @@ -1,11 +1,12 @@ import HRE from 'hardhat' -import { time, impersonate } from '../../../common/testutil' +import { time, impersonate } from '../../../../common/testutil' import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { FakeContract, smock } from '@defi-wonderland/smock' import { expect, use } from 'chai' import { IERC20Metadata, IERC20Metadata__factory, + IController, IController__factory, IProduct, IProduct__factory, @@ -15,19 +16,21 @@ import { IOracleProvider, ICollateral, ICollateral__factory, -} from '../../types/generated' +} from '../../../types/generated' import { BigNumber, constants, utils } from 'ethers' const { config, ethers } = HRE use(smock.matchers) -const DSU_HOLDER = '0xaef566ca7e84d1e736f999765a804687f39d9094' +const DSU_MINTER = '0xD05aCe63789cCb35B9cE71d01e4d632a0486Da4B' describe('BalancedVault', () => { let vault: BalancedVault let asset: IERC20Metadata let oracle: FakeContract let collateral: ICollateral + let controller: IController + let controllerOwner: SignerWithAddress let owner: SignerWithAddress let user: SignerWithAddress let user2: SignerWithAddress @@ -51,6 +54,11 @@ describe('BalancedVault', () => { oracle.atVersion.whenCalledWith(newVersion.version).returns(newVersion) } + async function updateOracleAndSync(newPrice?: BigNumber) { + await updateOracle(newPrice) + await vault.sync() + } + async function longPosition() { return (await long.position(vault.address)).maker } @@ -76,27 +84,36 @@ describe('BalancedVault', () => { ;[owner, user, user2, liquidator, perennialUser] = await ethers.getSigners() const dsu = IERC20Metadata__factory.connect('0x605D26FBd5be761089281d5cec2Ce86eeA667109', owner) - const controller = IController__factory.connect('0x9df509186b6d3b7D033359f94c8b1BB5544d51b3', owner) + controller = IController__factory.connect('0x9df509186b6d3b7D033359f94c8b1BB5544d51b3', owner) + controllerOwner = await impersonate.impersonateWithBalance( + await controller.callStatic['owner()'](), + utils.parseEther('10'), + ) long = IProduct__factory.connect('0xdB60626FF6cDC9dB07d3625A93d21dDf0f8A688C', owner) short = IProduct__factory.connect('0xfeD3E166330341e0305594B8c6e6598F9f4Cbe9B', owner) collateral = ICollateral__factory.connect('0x2d264ebdb6632a06a1726193d4d37fef1e5dbdcd', owner) leverage = utils.parseEther('4.0') maxCollateral = utils.parseEther('500000') - vault = await new BalancedVault__factory(owner).deploy( - dsu.address, - controller.address, - long.address, - short.address, - leverage, - maxCollateral, - ) - await vault.initialize('Perennial Vault Alpha', 'PVA') + vault = await new BalancedVault__factory(owner).deploy(dsu.address, controller.address, leverage, maxCollateral, [ + { + long: long.address, + short: short.address, + weight: 1, + }, + ]) + await vault.initialize('Perennial Vault Alpha') asset = IERC20Metadata__factory.connect(await vault.asset(), owner) - const dsuHolder = await impersonate.impersonateWithBalance(DSU_HOLDER, utils.parseEther('10')) + const dsuMinter = await impersonate.impersonateWithBalance(DSU_MINTER, utils.parseEther('10')) const setUpWalletWithDSU = async (wallet: SignerWithAddress) => { - await dsu.connect(dsuHolder).transfer(wallet.address, utils.parseEther('200000')) + const dsuIface = new utils.Interface(['function mint(uint256)']) + await dsuMinter.sendTransaction({ + to: dsu.address, + value: 0, + data: dsuIface.encodeFunctionData('mint', [utils.parseEther('200000')]), + }) + await dsu.connect(dsuMinter).transfer(wallet.address, utils.parseEther('200000')) await dsu.connect(wallet).approve(vault.address, ethers.constants.MaxUint256) } await setUpWalletWithDSU(user) @@ -104,6 +121,9 @@ describe('BalancedVault', () => { await setUpWalletWithDSU(liquidator) await setUpWalletWithDSU(perennialUser) await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) // Unfortunately, we can't make mocks of existing contracts. // So, we make a fake and initialize it with the values that the real contract had at this block. @@ -121,7 +141,7 @@ describe('BalancedVault', () => { describe('#initialize', () => { it('cant re-initialize', async () => { - await expect(vault.initialize('Perennial Vault Alpha', 'PVA')).to.revertedWithCustomError( + await expect(vault.initialize('Perennial Vault Alpha')).to.revertedWithCustomError( vault, 'UInitializableAlreadyInitializedError', ) @@ -134,18 +154,6 @@ describe('BalancedVault', () => { }) }) - describe('#symbol', () => { - it('is correct', async () => { - expect(await vault.symbol()).to.equal('PVA') - }) - }) - - describe('#decimals', () => { - it('is correct', async () => { - expect(await vault.decimals()).to.equal(18) - }) - }) - describe('#approve', () => { it('approves correctly', async () => { expect(await vault.allowance(user.address, liquidator.address)).to.eq(0) @@ -164,112 +172,6 @@ describe('BalancedVault', () => { }) }) - describe('#transfer', () => { - const EXPECTED_BALANCE_OF = utils.parseEther('10000') - beforeEach(async () => { - await vault.connect(user).deposit(EXPECTED_BALANCE_OF, user.address) - await updateOracle() - await vault.sync() - }) - - it('transfers correctly', async () => { - expect(await vault.balanceOf(user.address)).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.balanceOf(user2.address)).to.equal(0) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - - await expect(vault.connect(user).transfer(user2.address, EXPECTED_BALANCE_OF.div(2))) - .to.emit(vault, 'Transfer') - .withArgs(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)) - - expect(await vault.balanceOf(user.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - expect(await vault.balanceOf(user2.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - - await expect(vault.connect(user).transfer(user2.address, EXPECTED_BALANCE_OF.div(2))) - .to.emit(vault, 'Transfer') - .withArgs(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)) - - expect(await vault.balanceOf(user.address)).to.equal(0) - expect(await vault.balanceOf(user2.address)).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - }) - }) - - describe('#transferFrom', () => { - const EXPECTED_BALANCE_OF = utils.parseEther('10000') - beforeEach(async () => { - await vault.connect(user).deposit(EXPECTED_BALANCE_OF, user.address) - await updateOracle() - await vault.sync() - }) - - it('transfers from approved correctly', async () => { - await vault.connect(user).approve(liquidator.address, EXPECTED_BALANCE_OF) - - expect(await vault.balanceOf(user.address)).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.balanceOf(user2.address)).to.equal(0) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.allowance(user.address, liquidator.address)).to.equal(EXPECTED_BALANCE_OF) - - await expect(vault.connect(liquidator).transferFrom(user.address, user2.address, EXPECTED_BALANCE_OF.div(2))) - .to.emit(vault, 'Transfer') - .withArgs(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)) - - expect(await vault.balanceOf(user.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - expect(await vault.balanceOf(user2.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.allowance(user.address, liquidator.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - - await expect(vault.connect(liquidator).transferFrom(user.address, user2.address, EXPECTED_BALANCE_OF.div(2))) - .to.emit(vault, 'Transfer') - .withArgs(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)) - - expect(await vault.balanceOf(user.address)).to.equal(0) - expect(await vault.balanceOf(user2.address)).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.allowance(user.address, liquidator.address)).to.equal(0) - }) - - it('transfers from approved correctly (infinite)', async () => { - await vault.connect(user).approve(liquidator.address, constants.MaxUint256) - - expect(await vault.balanceOf(user.address)).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.balanceOf(user2.address)).to.equal(0) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.allowance(user.address, liquidator.address)).to.equal(constants.MaxUint256) - - await expect(vault.connect(liquidator).transferFrom(user.address, user2.address, EXPECTED_BALANCE_OF.div(2))) - .to.emit(vault, 'Transfer') - .withArgs(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)) - - expect(await vault.balanceOf(user.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - expect(await vault.balanceOf(user2.address)).to.equal(EXPECTED_BALANCE_OF.div(2)) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.allowance(user.address, liquidator.address)).to.equal(constants.MaxUint256) - - await expect(vault.connect(liquidator).transferFrom(user.address, user2.address, EXPECTED_BALANCE_OF.div(2))) - .to.emit(vault, 'Transfer') - .withArgs(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)) - - expect(await vault.balanceOf(user.address)).to.equal(0) - expect(await vault.balanceOf(user2.address)).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.totalSupply()).to.equal(EXPECTED_BALANCE_OF) - expect(await vault.allowance(user.address, liquidator.address)).to.equal(constants.MaxUint256) - }) - - it('reverts when spender is unapproved', async () => { - await expect( - vault.connect(liquidator).transferFrom(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)), - ).to.revertedWithPanic('0x11') - }) - - it('reverts when spender is unapproved (self)', async () => { - await expect( - vault.connect(user).transferFrom(user.address, user2.address, EXPECTED_BALANCE_OF.div(2)), - ).to.revertedWithPanic('0x11') - }) - }) - describe('#deposit/#redeem/#claim/#sync', () => { it('simple deposits and withdraws', async () => { expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) @@ -497,132 +399,6 @@ describe('BalancedVault', () => { expect(await vault.totalUnclaimed()).to.equal(0) }) - it('transferring shares', async () => { - const smallDeposit = utils.parseEther('10') - await vault.connect(user).deposit(smallDeposit, user.address) - expect(await longCollateralInVault()).to.equal(0) - expect(await shortCollateralInVault()).to.equal(0) - await updateOracle() - await vault.sync() - - // We're underneath the collateral minimum, so we shouldn't have opened any positions. - expect(await longPosition()).to.equal(0) - expect(await shortPosition()).to.equal(0) - - const largeDeposit = utils.parseEther('10000') - await vault.connect(user).deposit(largeDeposit, user.address) - expect(await longCollateralInVault()).to.equal(utils.parseEther('5005')) - expect(await shortCollateralInVault()).to.equal(utils.parseEther('5005')) - await updateOracle() - - await vault.sync() - expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('10010')) - expect(await vault.totalSupply()).to.equal(utils.parseEther('10010')) - - // Now we should have opened positions. - // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. - expect(await longPosition()).to.equal( - smallDeposit.add(largeDeposit).mul(leverage).div(2).div(originalOraclePrice), - ) - expect(await shortPosition()).to.equal( - smallDeposit.add(largeDeposit).mul(leverage).div(2).div(originalOraclePrice), - ) - - // User 2 should not be able to withdraw; they haven't deposited anything. - await expect(vault.connect(user2).redeem(1, user2.address)).to.be.revertedWithCustomError( - vault, - 'BalancedVaultRedemptionLimitExceeded', - ) - - // Transfer all of user's shares to user2 - await vault.connect(user).transfer(user2.address, utils.parseEther('10010')) - expect(await vault.balanceOf(user.address)).to.equal(0) - expect(await vault.balanceOf(user2.address)).to.equal(utils.parseEther('10010')) - expect(await vault.totalSupply()).to.equal(utils.parseEther('10010')) - // Now User should not be able to withdraw as they have no more shares - await expect(vault.connect(user).redeem(1, user.address)).to.be.revertedWithCustomError( - vault, - 'BalancedVaultRedemptionLimitExceeded', - ) - - expect(await vault.maxRedeem(user2.address)).to.equal(utils.parseEther('10010')) - await vault.connect(user2).redeem(await vault.maxRedeem(user2.address), user2.address) - await updateOracle() - await vault.sync() - - // We should have closed all positions. - expect(await longPosition()).to.equal(0) - expect(await shortPosition()).to.equal(0) - - // We should have withdrawn all of our collateral. - const fundingAmount = BigNumber.from('1526207855124') - const totalClaimable = utils.parseEther('10010').add(fundingAmount) - expect(await totalCollateralInVault()).to.equal(totalClaimable) - expect(await vault.totalAssets()).to.equal(0) - expect(await vault.unclaimed(user2.address)).to.equal(totalClaimable) - expect(await vault.totalUnclaimed()).to.equal(totalClaimable) - - await vault.connect(user2).claim(user2.address) - expect(await totalCollateralInVault()).to.equal(0) - expect(await vault.totalAssets()).to.equal(0) - expect(await asset.balanceOf(user2.address)).to.equal(utils.parseEther('200000').add(totalClaimable)) - }) - - it('partial transfers using transferFrom', async () => { - const smallDeposit = utils.parseEther('10') - await vault.connect(user).deposit(smallDeposit, user.address) - await updateOracle() - await vault.sync() - - const largeDeposit = utils.parseEther('10000') - await vault.connect(user).deposit(largeDeposit, user.address) - await updateOracle() - await vault.sync() - - // Now we should have opened positions. - // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. - expect(await longPosition()).to.be.equal( - smallDeposit.add(largeDeposit).mul(leverage).div(2).div(originalOraclePrice), - ) - expect(await shortPosition()).to.equal( - smallDeposit.add(largeDeposit).mul(leverage).div(2).div(originalOraclePrice), - ) - - // Setup approval - const shareBalance = await vault.balanceOf(user.address) - await vault.connect(user).approve(owner.address, shareBalance.div(2)) - await vault.connect(owner).transferFrom(user.address, user2.address, shareBalance.div(2)) - expect(await vault.balanceOf(user.address)).to.equal(shareBalance.sub(shareBalance.div(2))) - expect(await vault.balanceOf(user2.address)).to.equal(shareBalance.div(2)) - expect(await vault.totalSupply()).to.equal(shareBalance) - - const maxRedeem = await vault.maxRedeem(user.address) - await vault.connect(user).redeem(maxRedeem, user.address) - const maxRedeem2 = await vault.maxRedeem(user2.address) - await vault.connect(user2).redeem(maxRedeem2, user2.address) - await updateOracle() - await vault.sync() - - // We should have closed all positions. - expect(await longPosition()).to.equal(0) - expect(await shortPosition()).to.equal(0) - - // We should have withdrawn all of our collateral. - await vault.connect(user).claim(user.address) - await vault.connect(user2).claim(user2.address) - - const fundingAmount = BigNumber.from('1526207855124') - const totalAssetsIn = utils.parseEther('10010') - expect(await totalCollateralInVault()).to.equal(0) - expect(await vault.totalAssets()).to.equal(0) - expect(await asset.balanceOf(user.address)).to.equal( - utils.parseEther('200000').sub(totalAssetsIn.div(2)).add(fundingAmount.div(2)), - ) - expect(await asset.balanceOf(user2.address)).to.equal( - utils.parseEther('200000').add(totalAssetsIn.div(2)).add(fundingAmount.div(2)), - ) - }) - it('maxWithdraw', async () => { const smallDeposit = utils.parseEther('500') await vault.connect(user).deposit(smallDeposit, user.address) @@ -837,6 +613,62 @@ describe('BalancedVault', () => { expect(await shortPosition()).to.equal(0) }) + it('close to taker', async () => { + // Deposit should create a greater position than what's available + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracle() + await vault.sync() + + // Get taker product very close to the maker + await asset.connect(perennialUser).approve(collateral.address, constants.MaxUint256) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, short.address, utils.parseEther('1000000')) + await short.connect(perennialUser).openTake(utils.parseEther('1280')) + await updateOracle() + await vault.sync() + + // Redeem should create a greater position delta than what's available + await vault.connect(user).redeem(utils.parseEther('5000'), user.address) + await updateOracle() + await vault.sync() + + const takerMinimum = BigNumber.from('6692251470872433151') + expect(await shortPosition()).to.equal(takerMinimum) + expect((await short.positionAtVersion(await short['latestVersion()']()))[0]).to.equal( + (await short.positionAtVersion(await short['latestVersion()']()))[1], + ) + }) + + it('product closing closes all positions', async () => { + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracleAndSync() + + expect(await longPosition()).to.be.greaterThan(0) + expect(await shortPosition()).to.be.greaterThan(0) + const productOwner = await impersonate.impersonateWithBalance( + await controller['owner(address)'](long.address), + utils.parseEther('10'), + ) + await long.connect(productOwner).updateClosed(true) + await updateOracleAndSync() + await updateOracleAndSync() + + // We should have closed all positions + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + + await long.connect(productOwner).updateClosed(false) + await updateOracleAndSync() + await updateOracleAndSync() + + // Positions should be opened back up again + expect(await longPosition()).to.be.greaterThan(0) + expect(await shortPosition()).to.be.greaterThan(0) + }) + context('liquidation', () => { context('long', () => { it('recovers before being liquidated', async () => { diff --git a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts new file mode 100644 index 00000000..b81baeb3 --- /dev/null +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts @@ -0,0 +1,1407 @@ +import HRE from 'hardhat' +import { time, impersonate } from '../../../../common/testutil' +import { deployProductOnMainnetFork } from '../helpers/setupHelpers' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { FakeContract, smock } from '@defi-wonderland/smock' +import { expect, use } from 'chai' +import { + IERC20Metadata, + IERC20Metadata__factory, + IController, + IController__factory, + IProduct, + IProduct__factory, + BalancedVault, + BalancedVault__factory, + IOracleProvider__factory, + IOracleProvider, + ICollateral, + ICollateral__factory, + ChainlinkOracle__factory, +} from '../../../types/generated' +import { BigNumber, constants, utils } from 'ethers' +import { product } from '@equilibria/perennial/types/generated/contracts' + +const { config, ethers } = HRE +use(smock.matchers) + +const DSU_MINTER = '0xD05aCe63789cCb35B9cE71d01e4d632a0486Da4B' + +describe.only('BalancedVault (Multi-Payoff)', () => { + let vault: BalancedVault + let asset: IERC20Metadata + let oracle: FakeContract + let collateral: ICollateral + let controller: IController + let controllerOwner: SignerWithAddress + let owner: SignerWithAddress + let user: SignerWithAddress + let user2: SignerWithAddress + let perennialUser: SignerWithAddress + let liquidator: SignerWithAddress + let long: IProduct + let short: IProduct + let leverage: BigNumber + let maxCollateral: BigNumber + let originalOraclePrice: BigNumber + let btcOriginalOraclePrice: BigNumber + let btcOracle: FakeContract + let btcLong: IProduct + let btcShort: IProduct + + async function updateOracle(newPrice?: BigNumber, newPriceBtc?: BigNumber) { + await updateOracleEth(newPrice) + await updateOracleBtc(newPriceBtc) + } + + async function updateOracleEth(newPrice?: BigNumber) { + const [currentVersion, currentTimestamp, currentPrice] = await oracle.currentVersion() + const newVersion = { + version: currentVersion.add(1), + timestamp: currentTimestamp.add(13), + price: newPrice ?? currentPrice, + } + oracle.sync.returns(newVersion) + oracle.currentVersion.returns(newVersion) + oracle.atVersion.whenCalledWith(newVersion.version).returns(newVersion) + } + + async function updateOracleBtc(newPrice?: BigNumber) { + const [currentVersion, currentTimestamp, currentPrice] = await btcOracle.currentVersion() + const newVersion = { + version: currentVersion.add(1), + timestamp: currentTimestamp.add(13), + price: newPrice ?? currentPrice, + } + btcOracle.sync.returns(newVersion) + btcOracle.currentVersion.returns(newVersion) + btcOracle.atVersion.whenCalledWith(newVersion.version).returns(newVersion) + } + + async function updateOracleAndSync(newPrice?: BigNumber) { + await updateOracle(newPrice) + await vault.sync() + } + + async function longPosition() { + return (await long.position(vault.address)).maker + } + + async function shortPosition() { + return (await short.position(vault.address)).maker + } + + async function btcLongPosition() { + return (await btcLong.position(vault.address)).maker + } + + async function btcShortPosition() { + return (await btcShort.position(vault.address)).maker + } + + async function longCollateralInVault() { + return await collateral['collateral(address,address)'](vault.address, long.address) + } + + async function shortCollateralInVault() { + return await collateral['collateral(address,address)'](vault.address, short.address) + } + + async function btcLongCollateralInVault() { + return await collateral['collateral(address,address)'](vault.address, btcLong.address) + } + + async function btcShortCollateralInVault() { + return await collateral['collateral(address,address)'](vault.address, btcShort.address) + } + + async function totalCollateralInVault() { + return (await longCollateralInVault()) + .add(await shortCollateralInVault()) + .add(await btcLongCollateralInVault()) + .add(await btcShortCollateralInVault()) + .add(await asset.balanceOf(vault.address)) + } + + beforeEach(async () => { + await time.reset(config) + let btcUser1, btcUser2 + ;[owner, user, user2, liquidator, perennialUser, btcUser1, btcUser2] = await ethers.getSigners() + + const dsu = IERC20Metadata__factory.connect('0x605D26FBd5be761089281d5cec2Ce86eeA667109', owner) + controller = IController__factory.connect('0x9df509186b6d3b7D033359f94c8b1BB5544d51b3', owner) + controllerOwner = await impersonate.impersonateWithBalance( + await controller.callStatic['owner()'](), + utils.parseEther('10'), + ) + long = IProduct__factory.connect('0xdB60626FF6cDC9dB07d3625A93d21dDf0f8A688C', owner) + short = IProduct__factory.connect('0xfeD3E166330341e0305594B8c6e6598F9f4Cbe9B', owner) + const btcOracleToMock = await new ChainlinkOracle__factory(owner).deploy( + '0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf', + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + '0x0000000000000000000000000000000000000348', + ) + btcLong = await deployProductOnMainnetFork({ + owner: owner, + name: 'Bitcoin', + symbol: 'BTC', + baseCurrency: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + quoteCurrency: '0x0000000000000000000000000000000000000348', + oracle: btcOracleToMock.address, + short: false, + }) + btcShort = await deployProductOnMainnetFork({ + owner: owner, + name: 'Bitcoin', + symbol: 'BTC', + baseCurrency: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + quoteCurrency: '0x0000000000000000000000000000000000000348', + oracle: btcOracleToMock.address, + short: true, + }) + collateral = ICollateral__factory.connect('0x2d264ebdb6632a06a1726193d4d37fef1e5dbdcd', owner) + leverage = utils.parseEther('4.0') + maxCollateral = utils.parseEther('500000') + + vault = await new BalancedVault__factory(owner).deploy(dsu.address, controller.address, leverage, maxCollateral, [ + { + long: long.address, + short: short.address, + weight: 4, + }, + { + long: btcLong.address, + short: btcShort.address, + weight: 1, + }, + ]) + await vault.initialize('Perennial Vault Alpha') + asset = IERC20Metadata__factory.connect(await vault.asset(), owner) + + const dsuMinter = await impersonate.impersonateWithBalance(DSU_MINTER, utils.parseEther('10')) + const setUpWalletWithDSU = async (wallet: SignerWithAddress) => { + const dsuIface = new utils.Interface(['function mint(uint256)']) + await dsuMinter.sendTransaction({ + to: dsu.address, + value: 0, + data: dsuIface.encodeFunctionData('mint', [utils.parseEther('200000')]), + }) + await dsu.connect(dsuMinter).transfer(wallet.address, utils.parseEther('200000')) + await dsu.connect(wallet).approve(vault.address, ethers.constants.MaxUint256) + } + await setUpWalletWithDSU(user) + await setUpWalletWithDSU(user2) + await setUpWalletWithDSU(liquidator) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(perennialUser) + await setUpWalletWithDSU(btcUser1) + await setUpWalletWithDSU(btcUser2) + + // Seed BTC markets with some activity + await dsu.connect(btcUser1).approve(collateral.address, ethers.constants.MaxUint256) + await dsu.connect(btcUser2).approve(collateral.address, ethers.constants.MaxUint256) + await collateral.connect(btcUser1).depositTo(btcUser1.address, btcLong.address, utils.parseEther('100000')) + await btcLong.connect(btcUser1).openMake(utils.parseEther('20')) + await collateral.connect(btcUser1).depositTo(btcUser1.address, btcShort.address, utils.parseEther('100000')) + await btcShort.connect(btcUser1).openMake(utils.parseEther('20')) + await collateral.connect(btcUser2).depositTo(btcUser2.address, btcLong.address, utils.parseEther('100000')) + await btcLong.connect(btcUser2).openTake(utils.parseEther('10')) + await collateral.connect(btcUser2).depositTo(btcUser2.address, btcShort.address, utils.parseEther('100000')) + await btcShort.connect(btcUser2).openTake(utils.parseEther('10')) + + // Unfortunately, we can't make mocks of existing contracts. + // So, we make a fake and initialize it with the values that the real contract had at this block. + const realOracle = IOracleProvider__factory.connect('0xA59eF0208418559770a48D7ae4f260A28763167B', owner) + const currentVersion = await realOracle.currentVersion() + originalOraclePrice = currentVersion[2] + + oracle = await smock.fake('IOracleProvider', { + address: '0x2C19eac953048801FfE1358D109A1Ac2aF7930fD', + }) + oracle.sync.returns(currentVersion) + oracle.currentVersion.returns(currentVersion) + oracle.atVersion.whenCalledWith(currentVersion[0]).returns(currentVersion) + + const realBtcOracle = await new ChainlinkOracle__factory(owner).deploy( + '0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf', + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + '0x0000000000000000000000000000000000000348', + ) + const btcCurrentVersion = await realBtcOracle.currentVersion() + btcOriginalOraclePrice = btcCurrentVersion[2] + + btcOracle = await smock.fake('IOracleProvider', { + address: btcOracleToMock.address, + }) + btcOracle.sync.returns(btcCurrentVersion) + btcOracle.currentVersion.returns(btcCurrentVersion) + btcOracle.atVersion.whenCalledWith(btcCurrentVersion[0]).returns(btcCurrentVersion) + }) + + describe('#initialize', () => { + it('cant re-initialize', async () => { + await expect(vault.initialize('Perennial Vault Alpha')).to.revertedWithCustomError( + vault, + 'UInitializableAlreadyInitializedError', + ) + }) + }) + + describe('#name', () => { + it('is correct', async () => { + expect(await vault.name()).to.equal('Perennial Vault Alpha') + }) + }) + + describe('#approve', () => { + it('approves correctly', async () => { + expect(await vault.allowance(user.address, liquidator.address)).to.eq(0) + + await expect(vault.connect(user).approve(liquidator.address, utils.parseEther('10'))) + .to.emit(vault, 'Approval') + .withArgs(user.address, liquidator.address, utils.parseEther('10')) + + expect(await vault.allowance(user.address, liquidator.address)).to.eq(utils.parseEther('10')) + + await expect(vault.connect(user).approve(liquidator.address, 0)) + .to.emit(vault, 'Approval') + .withArgs(user.address, liquidator.address, 0) + + expect(await vault.allowance(user.address, liquidator.address)).to.eq(0) + }) + }) + + describe('#deposit/#redeem/#claim/#sync', () => { + it('simple deposits and withdraws', async () => { + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + + const smallDeposit = utils.parseEther('10') + await vault.connect(user).deposit(smallDeposit, user.address) + expect(await longCollateralInVault()).to.equal(0) + expect(await shortCollateralInVault()).to.equal(0) + expect(await btcLongCollateralInVault()).to.equal(0) + expect(await btcShortCollateralInVault()).to.equal(0) + expect(await vault.totalSupply()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + await updateOracle() + await vault.sync() + + // We're underneath the collateral minimum, so we shouldn't have opened any positions. + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + expect(await longCollateralInVault()).to.equal(utils.parseEther('4004')) + expect(await shortCollateralInVault()).to.equal(utils.parseEther('4004')) + expect(await btcLongCollateralInVault()).to.equal(utils.parseEther('1001')) + expect(await btcShortCollateralInVault()).to.equal(utils.parseEther('1001')) + expect(await vault.balanceOf(user.address)).to.equal(smallDeposit) + expect(await vault.totalSupply()).to.equal(smallDeposit) + expect(await vault.totalAssets()).to.equal(smallDeposit) + expect(await vault.convertToAssets(utils.parseEther('10'))).to.equal(utils.parseEther('10')) + expect(await vault.convertToShares(utils.parseEther('10'))).to.equal(utils.parseEther('10')) + await updateOracle() + await vault.sync() + + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('10010')) + expect(await vault.totalSupply()).to.equal(utils.parseEther('10010')) + expect(await vault.totalAssets()).to.equal(utils.parseEther('10010')) + expect(await vault.convertToAssets(utils.parseEther('10010'))).to.equal(utils.parseEther('10010')) + expect(await vault.convertToShares(utils.parseEther('10010'))).to.equal(utils.parseEther('10010')) + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.equal( + smallDeposit.add(largeDeposit).mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await shortPosition()).to.equal( + smallDeposit.add(largeDeposit).mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await btcLongPosition()).to.equal( + smallDeposit.add(largeDeposit).mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + expect(await btcShortPosition()).to.equal( + smallDeposit.add(largeDeposit).mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + + // User 2 should not be able to withdraw; they haven't deposited anything. + await expect(vault.connect(user2).redeem(1, user2.address)).to.be.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + expect(await vault.maxRedeem(user.address)).to.equal(utils.parseEther('10010')) + await vault.connect(user).redeem(await vault.maxRedeem(user.address), user.address) + await updateOracle() + await vault.sync() + + // We should have closed all positions. + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('824939190034966') + expect(await totalCollateralInVault()).to.equal(utils.parseEther('10010').add(fundingAmount)) + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.totalSupply()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.unclaimed(user.address)).to.equal(utils.parseEther('10010').add(fundingAmount)) + expect(await vault.totalUnclaimed()).to.equal(utils.parseEther('10010').add(fundingAmount)) + + await vault.connect(user).claim(user.address) + expect(await totalCollateralInVault()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('200000').add(fundingAmount)) + expect(await vault.unclaimed(user.address)).to.equal(0) + expect(await vault.totalUnclaimed()).to.equal(0) + }) + + it('multiple users', async () => { + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + + const smallDeposit = utils.parseEther('1000') + await vault.connect(user).deposit(smallDeposit, user.address) + await updateOracle() + await vault.sync() + + const largeDeposit = utils.parseEther('10000') + await vault.connect(user2).deposit(largeDeposit, user2.address) + await updateOracle() + await vault.sync() + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.be.equal( + smallDeposit.add(largeDeposit).mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await shortPosition()).to.equal( + smallDeposit.add(largeDeposit).mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await btcLongPosition()).to.be.equal( + smallDeposit.add(largeDeposit).mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + expect(await btcShortPosition()).to.equal( + smallDeposit.add(largeDeposit).mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + const fundingAmount0 = BigNumber.from(83666424963960) + const balanceOf2 = BigNumber.from('9999999163335820361100') + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('1000')) + expect(await vault.balanceOf(user2.address)).to.equal(balanceOf2) + expect(await vault.totalAssets()).to.equal(utils.parseEther('11000').add(fundingAmount0)) + expect(await vault.totalSupply()).to.equal(utils.parseEther('1000').add(balanceOf2)) + expect(await vault.convertToAssets(utils.parseEther('1000').add(balanceOf2))).to.equal( + utils.parseEther('11000').add(fundingAmount0), + ) + expect(await vault.convertToShares(utils.parseEther('11000').add(fundingAmount0))).to.equal( + utils.parseEther('1000').add(balanceOf2), + ) + + const maxRedeem = await vault.maxRedeem(user.address) + await vault.connect(user).redeem(maxRedeem, user.address) + await updateOracle() + await vault.sync() + + const maxRedeem2 = await vault.maxRedeem(user2.address) + await vault.connect(user2).redeem(maxRedeem2, user2.address) + await updateOracle() + await vault.sync() + + // We should have closed all positions. + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('165941798239422') + const fundingAmount2 = BigNumber.from('1646882507931229') + expect(await totalCollateralInVault()).to.equal(utils.parseEther('11000').add(fundingAmount).add(fundingAmount2)) + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.balanceOf(user2.address)).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await vault.totalSupply()).to.equal(0) + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.unclaimed(user.address)).to.equal(utils.parseEther('1000').add(fundingAmount)) + expect(await vault.unclaimed(user2.address)).to.equal(utils.parseEther('10000').add(fundingAmount2)) + expect(await vault.totalUnclaimed()).to.equal(utils.parseEther('11000').add(fundingAmount).add(fundingAmount2)) + + await vault.connect(user).claim(user.address) + await vault.connect(user2).claim(user2.address) + + expect(await totalCollateralInVault()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('200000').add(fundingAmount)) + expect(await asset.balanceOf(user2.address)).to.equal(utils.parseEther('200000').add(fundingAmount2)) + expect(await vault.unclaimed(user2.address)).to.equal(0) + expect(await vault.totalUnclaimed()).to.equal(0) + }) + + it('deposit during withdraw', async () => { + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + + const smallDeposit = utils.parseEther('1000') + await vault.connect(user).deposit(smallDeposit, user.address) + await updateOracle() + await vault.sync() + + const largeDeposit = utils.parseEther('2000') + await vault.connect(user2).deposit(largeDeposit, user2.address) + await vault.connect(user).redeem(utils.parseEther('400'), user.address) + await updateOracle() + await vault.sync() + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.be.equal( + smallDeposit + .add(largeDeposit) + .sub(utils.parseEther('400')) + .mul(4) + .div(5) + .mul(leverage) + .div(2) + .div(originalOraclePrice), + ) + expect(await shortPosition()).to.equal( + smallDeposit + .add(largeDeposit) + .sub(utils.parseEther('400')) + .mul(4) + .div(5) + .mul(leverage) + .div(2) + .div(originalOraclePrice), + ) + expect(await btcLongPosition()).to.be.equal( + smallDeposit + .add(largeDeposit) + .sub(utils.parseEther('400')) + .div(5) + .mul(leverage) + .div(2) + .div(btcOriginalOraclePrice), + ) + expect(await btcShortPosition()).to.equal( + smallDeposit + .add(largeDeposit) + .sub(utils.parseEther('400')) + .div(5) + .mul(leverage) + .div(2) + .div(btcOriginalOraclePrice), + ) + const fundingAmount0 = BigNumber.from('50199854978376') + const balanceOf2 = BigNumber.from('1999999832667164072220') + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('600')) + expect(await vault.balanceOf(user2.address)).to.equal(balanceOf2) + expect(await vault.totalAssets()).to.equal(utils.parseEther('2600').add(fundingAmount0)) + expect(await totalCollateralInVault()).to.equal( + utils + .parseEther('2600') + .add(fundingAmount0) + .add(await vault.totalUnclaimed()), + ) + expect(await vault.totalSupply()).to.equal(utils.parseEther('600').add(balanceOf2)) + expect(await vault.convertToAssets(utils.parseEther('600').add(balanceOf2))).to.equal( + utils.parseEther('2600').add(fundingAmount0), + ) + expect(await vault.convertToShares(utils.parseEther('2600').add(fundingAmount0))).to.equal( + utils.parseEther('600').add(balanceOf2), + ) + + const maxRedeem = await vault.maxRedeem(user.address) + await vault.connect(user).redeem(maxRedeem, user.address) + await updateOracle() + await vault.sync() + + const maxRedeem2 = await vault.maxRedeem(user2.address) + await vault.connect(user2).redeem(maxRedeem2, user2.address) + await updateOracle() + await vault.sync() + + // We should have closed all positions. + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('133731306363245') + const fundingAmount2 = BigNumber.from('333934356519138') + expect(await totalCollateralInVault()).to.equal(utils.parseEther('3000').add(fundingAmount).add(fundingAmount2)) + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.balanceOf(user2.address)).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await vault.totalSupply()).to.equal(0) + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.unclaimed(user.address)).to.equal(utils.parseEther('1000').add(fundingAmount)) + expect(await vault.unclaimed(user2.address)).to.equal(utils.parseEther('2000').add(fundingAmount2)) + expect(await vault.totalUnclaimed()).to.equal(utils.parseEther('3000').add(fundingAmount).add(fundingAmount2)) + + await vault.connect(user).claim(user.address) + await vault.connect(user2).claim(user2.address) + + expect(await totalCollateralInVault()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('200000').add(fundingAmount)) + expect(await asset.balanceOf(user2.address)).to.equal(utils.parseEther('200000').add(fundingAmount2)) + expect(await vault.unclaimed(user2.address)).to.equal(0) + expect(await vault.totalUnclaimed()).to.equal(0) + }) + + it('oracles offset', async () => { + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + + const smallDeposit = utils.parseEther('1000') + await vault.connect(user).deposit(smallDeposit, user.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + const largeDeposit = utils.parseEther('10000') + const assetsForPosition = (await vault.totalAssets()).add(largeDeposit) + await vault.connect(user2).deposit(largeDeposit, user2.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.be.equal( + assetsForPosition.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await shortPosition()).to.equal( + assetsForPosition.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await btcLongPosition()).to.be.equal( + assetsForPosition.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + expect(await btcShortPosition()).to.equal( + assetsForPosition.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + const fundingAmount0 = BigNumber.from(88080044500152) + const balanceOf2 = BigNumber.from('9999999159583484821247') + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('1000')) + expect(await vault.balanceOf(user2.address)).to.equal(balanceOf2) + expect(await vault.totalAssets()).to.equal(utils.parseEther('11000').add(fundingAmount0)) + expect(await vault.totalSupply()).to.equal(utils.parseEther('1000').add(balanceOf2)) + expect(await vault.convertToAssets(utils.parseEther('1000').add(balanceOf2))).to.equal( + utils.parseEther('11000').add(fundingAmount0), + ) + expect(await vault.convertToShares(utils.parseEther('11000').add(fundingAmount0))).to.equal( + utils.parseEther('1000').add(balanceOf2), + ) + + const maxRedeem = await vault.maxRedeem(user.address) + await vault.connect(user).redeem(maxRedeem, user.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + const maxRedeem2 = await vault.maxRedeem(user2.address) + await vault.connect(user2).redeem(maxRedeem2, user2.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + // We should have closed all positions. + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('166684157907894') + const fundingAmount2 = BigNumber.from('1654233009885413') + expect(await totalCollateralInVault()).to.equal(utils.parseEther('11000').add(fundingAmount).add(fundingAmount2)) + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.balanceOf(user2.address)).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await vault.totalSupply()).to.equal(0) + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.unclaimed(user.address)).to.equal(utils.parseEther('1000').add(fundingAmount)) + expect(await vault.unclaimed(user2.address)).to.equal(utils.parseEther('10000').add(fundingAmount2)) + expect(await vault.totalUnclaimed()).to.equal(utils.parseEther('11000').add(fundingAmount).add(fundingAmount2)) + + await vault.connect(user).claim(user.address) + await vault.connect(user2).claim(user2.address) + + expect(await totalCollateralInVault()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('200000').add(fundingAmount)) + expect(await asset.balanceOf(user2.address)).to.equal(utils.parseEther('200000').add(fundingAmount2)) + expect(await vault.unclaimed(user2.address)).to.equal(0) + expect(await vault.totalUnclaimed()).to.equal(0) + }) + + it('oracles offset during pending', async () => { + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + + const smallDeposit = utils.parseEther('1000') + await vault.connect(user).deposit(smallDeposit, user.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + const largeDeposit = utils.parseEther('10000') + await vault.connect(user2).deposit(largeDeposit, user2.address) + await updateOracleEth() + await vault.connect(user2).deposit(largeDeposit, user2.address) + let assetsForPosition = (await vault.totalAssets()).add(largeDeposit) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.be.equal( + assetsForPosition.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await shortPosition()).to.equal( + assetsForPosition.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await btcLongPosition()).to.be.equal( + assetsForPosition.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + expect(await btcShortPosition()).to.equal( + assetsForPosition.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + const fundingAmount0 = BigNumber.from(88080044500182) + const balanceOf2 = BigNumber.from('9999999159583484821247') + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('1000')) + expect(await vault.balanceOf(user2.address)).to.equal(balanceOf2) + expect(await vault.totalAssets()).to.equal(utils.parseEther('11000').add(fundingAmount0)) + expect(await vault.totalSupply()).to.equal(utils.parseEther('1000').add(balanceOf2)) + expect(await vault.convertToAssets(utils.parseEther('1000').add(balanceOf2))).to.equal( + utils.parseEther('11000').add(fundingAmount0), + ) + expect(await vault.convertToShares(utils.parseEther('11000').add(fundingAmount0))).to.equal( + utils.parseEther('1000').add(balanceOf2), + ) + + // Do another epoch update to get pending deposits in + assetsForPosition = (await vault.totalAssets()).add(largeDeposit) + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + await vault.syncAccount(user.address) + await vault.syncAccount(user2.address) + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.be.equal( + assetsForPosition.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await shortPosition()).to.equal( + assetsForPosition.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice), + ) + expect(await btcLongPosition()).to.be.equal( + assetsForPosition.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + expect(await btcShortPosition()).to.equal( + assetsForPosition.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice), + ) + const fundingAmount1 = BigNumber.from(993109081734194) + const balanceOf2_1 = BigNumber.from('19999997492742183569043') + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('1000')) + expect(await vault.balanceOf(user2.address)).to.equal(balanceOf2_1) + expect(await vault.totalAssets()).to.equal(utils.parseEther('21000').add(fundingAmount1)) + expect(await vault.totalSupply()).to.equal(utils.parseEther('1000').add(balanceOf2_1)) + expect(await vault.convertToAssets(utils.parseEther('1000').add(balanceOf2_1))).to.equal( + utils.parseEther('21000').add(fundingAmount1), + ) + expect(await vault.convertToShares(utils.parseEther('21000').add(fundingAmount1))).to.equal( + utils.parseEther('1000').add(balanceOf2_1), + ) + + const maxRedeem = await vault.maxRedeem(user.address) + await vault.connect(user).redeem(maxRedeem, user.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + await vault.connect(user2).redeem(utils.parseEther('10000'), user2.address) + await updateOracleEth() + const maxRedeem2 = await vault.maxRedeem(user2.address) + await vault.connect(user2).redeem(maxRedeem2, user2.address) + await updateOracleEth() + await updateOracleEth() + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + + await updateOracleEth() + await updateOracleBtc() + await vault.sync() + await vault.syncAccount(user.address) + await vault.syncAccount(user2.address) + + // We should have closed all positions. + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('247603340304160') + const fundingAmount2 = BigNumber.from('4900882935203790') + expect(await totalCollateralInVault()).to.equal(utils.parseEther('21000').add(fundingAmount).add(fundingAmount2)) + expect(await vault.balanceOf(user.address)).to.equal(0) + expect(await vault.balanceOf(user2.address)).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await vault.totalSupply()).to.equal(0) + expect(await vault.convertToAssets(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.convertToShares(utils.parseEther('1'))).to.equal(utils.parseEther('1')) + expect(await vault.unclaimed(user.address)).to.equal(utils.parseEther('1000').add(fundingAmount)) + expect(await vault.unclaimed(user2.address)).to.equal(utils.parseEther('20000').add(fundingAmount2)) + expect(await vault.totalUnclaimed()).to.equal(utils.parseEther('21000').add(fundingAmount).add(fundingAmount2)) + + await vault.connect(user).claim(user.address) + await vault.connect(user2).claim(user2.address) + + expect(await totalCollateralInVault()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('200000').add(fundingAmount)) + expect(await asset.balanceOf(user2.address)).to.equal(utils.parseEther('200000').add(fundingAmount2)) + expect(await vault.unclaimed(user2.address)).to.equal(0) + expect(await vault.totalUnclaimed()).to.equal(0) + }) + + it('maxWithdraw', async () => { + const smallDeposit = utils.parseEther('1000') + await vault.connect(user).deposit(smallDeposit, user.address) + await updateOracle() + await vault.sync() + + const shareAmount = BigNumber.from(utils.parseEther('1000')) + expect(await vault.maxRedeem(user.address)).to.equal(shareAmount) + + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracle() + await vault.sync() + + const shareAmount2 = BigNumber.from('9999999163335820361100') + expect(await vault.maxRedeem(user.address)).to.equal(shareAmount.add(shareAmount2)) + + // We shouldn't be able to withdraw more than maxWithdraw. + await expect( + vault.connect(user).redeem((await vault.maxRedeem(user.address)).add(1), user.address), + ).to.be.revertedWithCustomError(vault, 'BalancedVaultRedemptionLimitExceeded') + + // But we should be able to withdraw exactly maxWithdraw. + await vault.connect(user).redeem(await vault.maxRedeem(user.address), user.address) + + // The oracle price hasn't changed yet, so we shouldn't be able to withdraw any more. + expect(await vault.maxRedeem(user.address)).to.equal(0) + + // But if we update the oracle price, we should be able to withdraw the rest of our collateral. + await updateOracle() + await vault.sync() + + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + // Our collateral should be less than the fixedFloat and greater than 0. + await vault.claim(user.address) + expect(await totalCollateralInVault()).to.eq(0) + expect(await vault.totalAssets()).to.equal(0) + }) + + it('maxDeposit', async () => { + expect(await vault.maxDeposit(user.address)).to.equal(maxCollateral) + const depositSize = utils.parseEther('200000') + + await vault.connect(user).deposit(depositSize, user.address) + expect(await vault.maxDeposit(user.address)).to.equal(maxCollateral.sub(depositSize)) + + await vault.connect(user2).deposit(utils.parseEther('200000'), user2.address) + expect(await vault.maxDeposit(user.address)).to.equal(maxCollateral.sub(depositSize).sub(depositSize)) + + await vault.connect(liquidator).deposit(utils.parseEther('100000'), liquidator.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + + await expect(vault.connect(liquidator).deposit(1, liquidator.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + }) + + it('rebalances collateral', async () => { + await vault.connect(user).deposit(utils.parseEther('100000'), user.address) + await updateOracle() + await vault.sync() + + const originalTotalCollateral = await totalCollateralInVault() + + // Collaterals should be equal. + expect(await longCollateralInVault()).to.equal(await shortCollateralInVault()) + expect(await btcLongCollateralInVault()).to.equal(await btcShortCollateralInVault()) + + await updateOracle(utils.parseEther('1300')) + await long.connect(user).settleAccount(vault.address) + await short.connect(user).settleAccount(vault.address) + + // Collaterals should not be equal any more. + expect(await longCollateralInVault()).to.not.equal(await shortCollateralInVault()) + expect(await btcLongCollateralInVault()).to.equal(await btcShortCollateralInVault()) + + await vault.sync() + + // Collaterals should be equal again! + expect(await longCollateralInVault()).to.equal(await shortCollateralInVault()) + expect(await btcLongCollateralInVault()).to.equal(await btcShortCollateralInVault()) + + await updateOracle(originalOraclePrice) + await vault.sync() + + // Since the price changed then went back to the original, the total collateral should have increased. + const fundingAmount = BigNumber.from('14258756963781699') + expect(await totalCollateralInVault()).to.eq(originalTotalCollateral.add(fundingAmount)) + expect(await vault.totalAssets()).to.eq(originalTotalCollateral.add(fundingAmount)) + }) + + it('rounds deposits correctly', async () => { + const collateralDifference = async () => { + return (await longCollateralInVault()).sub(await shortCollateralInVault()).abs() + } + const btcCollateralDifference = async () => { + return (await btcLongCollateralInVault()).sub(await btcShortCollateralInVault()).abs() + } + const oddDepositAmount = utils.parseEther('10000').add(1) // 10K + 1 wei + + await vault.connect(user).deposit(oddDepositAmount, user.address) + await updateOracle() + await vault.sync() + expect(await collateralDifference()).to.equal(0) + expect(await btcCollateralDifference()).to.equal(0) + expect(await asset.balanceOf(vault.address)).to.equal(1) + + await vault.connect(user).deposit(oddDepositAmount, user.address) + await updateOracle() + await vault.sync() + expect(await collateralDifference()).to.equal(0) + expect(await btcCollateralDifference()).to.equal(0) + }) + + it('deposit on behalf', async () => { + const largeDeposit = utils.parseEther('10000') + await vault.connect(liquidator).deposit(largeDeposit, user.address) + await updateOracle() + + await vault.sync() + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('10000')) + expect(await vault.totalSupply()).to.equal(utils.parseEther('10000')) + + await expect(vault.connect(liquidator).redeem(utils.parseEther('10000'), user.address)).to.revertedWithPanic( + '0x11', + ) + + await vault.connect(user).approve(liquidator.address, utils.parseEther('10000')) + + // User 2 should not be able to withdraw; they haven't deposited anything. + await vault.connect(liquidator).redeem(utils.parseEther('10000'), user.address) + await updateOracle() + await vault.sync() + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('824128844013458') + await vault.connect(user).claim(user.address) + expect(await totalCollateralInVault()).to.equal(0) + expect(await vault.totalAssets()).to.equal(0) + expect(await asset.balanceOf(liquidator.address)).to.equal(utils.parseEther('190000')) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('210000').add(fundingAmount)) + }) + + it('redeem on behalf', async () => { + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracle() + + await vault.sync() + expect(await vault.balanceOf(user.address)).to.equal(utils.parseEther('10000')) + expect(await vault.totalSupply()).to.equal(utils.parseEther('10000')) + + await expect(vault.connect(liquidator).redeem(utils.parseEther('10000'), user.address)).to.revertedWithPanic( + '0x11', + ) + + await vault.connect(user).approve(liquidator.address, utils.parseEther('10000')) + + // User 2 should not be able to withdraw; they haven't deposited anything. + await vault.connect(liquidator).redeem(utils.parseEther('10000'), user.address) + await updateOracle() + await vault.sync() + + // We should have withdrawn all of our collateral. + const fundingAmount = BigNumber.from('824128844013458') + await vault.connect(user).claim(user.address) + expect(await totalCollateralInVault()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal(utils.parseEther('200000').add(fundingAmount)) + }) + + it('close to makerLimit', async () => { + // Get maker product very close to the makerLimit + await asset.connect(perennialUser).approve(collateral.address, constants.MaxUint256) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, short.address, utils.parseEther('400000')) + await short.connect(perennialUser).openMake(utils.parseEther('480')) + await updateOracle() + await vault.sync() + + // Deposit should create a greater position than what's available + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracle() + await vault.sync() + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.equal(largeDeposit.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice)) + const makerLimitDelta = BigNumber.from('8282802043703935198') + expect(await shortPosition()).to.equal(makerLimitDelta) + expect(await btcLongPosition()).to.equal(largeDeposit.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice)) + expect(await btcShortPosition()).to.equal(largeDeposit.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice)) + }) + + it('exactly at makerLimit', async () => { + // Get maker product very close to the makerLimit + await asset.connect(perennialUser).approve(collateral.address, constants.MaxUint256) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, short.address, utils.parseEther('400000')) + const makerAvailable = (await short.makerLimit()).sub( + (await short.positionAtVersion(await short['latestVersion()']())).maker, + ) + + await short.connect(perennialUser).openMake(makerAvailable) + await updateOracle() + await vault.sync() + + // Deposit should create a greater position than what's available + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracle() + await vault.sync() + + // Now we should have opened positions. + // The positions should be equal to (smallDeposit + largeDeposit) * leverage / 2 / originalOraclePrice. + expect(await longPosition()).to.equal(largeDeposit.mul(leverage).mul(4).div(5).div(2).div(originalOraclePrice)) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(largeDeposit.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice)) + expect(await btcShortPosition()).to.equal(largeDeposit.mul(leverage).div(5).div(2).div(btcOriginalOraclePrice)) + }) + + it('close to taker', async () => { + // Deposit should create a greater position than what's available + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracle() + await vault.sync() + + // Get taker product very close to the maker + await asset.connect(perennialUser).approve(collateral.address, constants.MaxUint256) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, short.address, utils.parseEther('1000000')) + await short.connect(perennialUser).openTake(utils.parseEther('1280')) + await updateOracle() + await vault.sync() + + // Redeem should create a greater position delta than what's available + await vault.connect(user).redeem(utils.parseEther('4000'), user.address) + await updateOracle() + await vault.sync() + + const takerMinimum = BigNumber.from('6692251470872433151') + expect(await shortPosition()).to.equal(takerMinimum) + expect((await short.positionAtVersion(await short['latestVersion()']()))[0]).to.equal( + (await short.positionAtVersion(await short['latestVersion()']()))[1], + ) + }) + + it('product closing closes all positions', async () => { + const largeDeposit = utils.parseEther('10000') + await vault.connect(user).deposit(largeDeposit, user.address) + await updateOracleAndSync() + + expect(await longPosition()).to.be.greaterThan(0) + expect(await shortPosition()).to.be.greaterThan(0) + expect(await btcLongPosition()).to.be.greaterThan(0) + expect(await btcShortPosition()).to.be.greaterThan(0) + const productOwner = await impersonate.impersonateWithBalance( + await controller['owner(address)'](long.address), + utils.parseEther('10'), + ) + await long.connect(productOwner).updateClosed(true) + await btcLong.connect(owner).updateClosed(true) + await updateOracleAndSync() + await updateOracleAndSync() + + // We should have closed all positions + expect(await longPosition()).to.equal(0) + expect(await shortPosition()).to.equal(0) + expect(await btcLongPosition()).to.equal(0) + expect(await btcShortPosition()).to.equal(0) + + await long.connect(productOwner).updateClosed(false) + await btcLong.connect(owner).updateClosed(false) + await updateOracleAndSync() + await updateOracleAndSync() + + // Positions should be opened back up again + expect(await longPosition()).to.be.greaterThan(0) + expect(await shortPosition()).to.be.greaterThan(0) + expect(await btcLongPosition()).to.be.greaterThan(0) + expect(await btcShortPosition()).to.be.greaterThan(0) + }) + + context('liquidation', () => { + context('long', () => { + it('recovers before being liquidated', async () => { + await vault.connect(user).deposit(utils.parseEther('100000'), user.address) + await updateOracle() + + // 1. An oracle update makes the long position liquidatable. + // We should now longer be able to deposit or redeem + await updateOracle(utils.parseEther('4000')) + + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 2. Settle accounts. + // We should still not be able to deposit. + await long.connect(user).settleAccount(vault.address) + await short.connect(user).settleAccount(vault.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 3. Sync the vault before it has a chance to get liquidated, it will work and no longer be liquidatable + // We should still be able to deposit. + await vault.sync() + expect(await vault.maxDeposit(user.address)).to.equal('401972181441895951577804') + await vault.connect(user).deposit(2, user.address) + }) + + it('recovers from a liquidation', async () => { + await vault.connect(user).deposit(utils.parseEther('100000'), user.address) + await updateOracle() + + // 1. An oracle update makes the long position liquidatable. + // We should now longer be able to deposit or redeem + await updateOracle(utils.parseEther('4000')) + + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 2. Settle accounts. + // We should still not be able to deposit or redeem. + await long.connect(user).settleAccount(vault.address) + await short.connect(user).settleAccount(vault.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 4. Liquidate the long position. + // We should still not be able to deposit or redeem. + await collateral.connect(liquidator).liquidate(vault.address, long.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 5. Settle the liquidation. + // We now be able to deposit. + await updateOracle(utils.parseEther('3000')) + await vault.connect(user).deposit(2, user.address) + + await updateOracle() + await vault.sync() + + const finalPosition = BigNumber.from('50707668091779666592') + const finalCollateral = BigNumber.from('38030753919602731122977') + const btcFinalPosition = BigNumber.from('1633897468743456266') + const btcFinalCollateral = BigNumber.from('9507688479900682780744') + expect(await longPosition()).to.equal(finalPosition) + expect(await shortPosition()).to.equal(finalPosition) + expect(await longCollateralInVault()).to.equal(finalCollateral) + expect(await shortCollateralInVault()).to.equal(finalCollateral) + expect(await btcLongPosition()).to.equal(btcFinalPosition) + expect(await btcShortPosition()).to.equal(btcFinalPosition) + expect(await btcLongCollateralInVault()).to.equal(btcFinalCollateral) + expect(await btcShortCollateralInVault()).to.equal(btcFinalCollateral) + }) + }) + + context('short', () => { + beforeEach(async () => { + // get utilization closer to target in order to trigger pnl on price deviation + await asset.connect(perennialUser).approve(collateral.address, constants.MaxUint256) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, long.address, utils.parseEther('120000')) + await long.connect(perennialUser).openTake(utils.parseEther('700')) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, short.address, utils.parseEther('280000')) + await short.connect(perennialUser).openTake(utils.parseEther('1100')) + await updateOracle() + await vault.sync() + }) + + it('recovers before being liquidated', async () => { + await vault.connect(user).deposit(utils.parseEther('100000'), user.address) + await updateOracle() + + // 1. An oracle update makes the short position liquidatable. + // We should now longer be able to deposit or redeem + await updateOracle(utils.parseEther('1200')) + + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 2. Settle accounts. + // We should still not be able to deposit. + await long.connect(user).settleAccount(vault.address) + await short.connect(user).settleAccount(vault.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 3. Sync the vault before it has a chance to get liquidated, it will work and no longer be liquidatable + // We should still be able to deposit. + await vault.sync() + expect(await vault.maxDeposit(user.address)).to.equal('396777266765732414363890') + await vault.connect(user).deposit(2, user.address) + }) + + it('recovers from a liquidation', async () => { + await vault.connect(user).deposit(utils.parseEther('100000'), user.address) + await updateOracle() + + // 1. An oracle update makes the long position liquidatable. + // We should now longer be able to deposit or redeem + await updateOracle(utils.parseEther('1200')) + + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 2. Settle accounts. + // We should still not be able to deposit or redeem. + await long.connect(user).settleAccount(vault.address) + await short.connect(user).settleAccount(vault.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 4. Liquidate the long position. + // We should still not be able to deposit or redeem. + await collateral.connect(liquidator).liquidate(vault.address, short.address) + expect(await vault.maxDeposit(user.address)).to.equal(0) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + await expect(vault.connect(user).redeem(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultRedemptionLimitExceeded', + ) + + // 5. Settle the liquidation. + // We now be able to deposit. + await updateOracle() + await vault.connect(user).deposit(2, user.address) + + await updateOracle() + await vault.sync() + + const finalPosition = BigNumber.from('136109459011782740553') + const finalCollateral = BigNumber.from('40832846402925697101225') + const btcFinalPosition = BigNumber.from('1754282213481988093') + const btcFinalCollateral = BigNumber.from('10208211600731424275306') + expect(await longPosition()).to.equal(finalPosition) + expect(await shortPosition()).to.equal(finalPosition) + expect(await longCollateralInVault()).to.equal(finalCollateral) + expect(await shortCollateralInVault()).to.equal(finalCollateral) + expect(await btcLongPosition()).to.equal(btcFinalPosition) + expect(await btcShortPosition()).to.equal(btcFinalPosition) + expect(await btcLongCollateralInVault()).to.equal(btcFinalCollateral) + expect(await btcShortCollateralInVault()).to.equal(btcFinalCollateral) + }) + }) + }) + + context('insolvency', () => { + beforeEach(async () => { + // get utilization closer to target in order to trigger pnl on price deviation + await asset.connect(perennialUser).approve(collateral.address, constants.MaxUint256) + await collateral + .connect(perennialUser) + .depositTo(perennialUser.address, long.address, utils.parseEther('120000')) + await long.connect(perennialUser).openTake(utils.parseEther('700')) + await updateOracle() + await vault.sync() + }) + + it('gracefully unwinds upon insolvency', async () => { + // 1. Deposit initial amount into the vault + await vault.connect(user).deposit(utils.parseEther('100000'), user.address) + await updateOracle() + await vault.sync() + + // 2. Redeem most of the amount, but leave it unclaimed + await vault.connect(user).redeem(utils.parseEther('80000'), user.address) + await updateOracle() + await vault.sync() + + // 3. An oracle update makes the long position liquidatable, initiate take close + await updateOracle(utils.parseEther('20000')) + await long.connect(user).settleAccount(vault.address) + await short.connect(user).settleAccount(vault.address) + await long.connect(perennialUser).closeTake(utils.parseEther('700')) + await collateral.connect(liquidator).liquidate(vault.address, long.address) + + // // 4. Settle the vault to recover and rebalance + await updateOracle() // let take settle at high price + await updateOracle(utils.parseEther('1500')) // return to normal price to let vault rebalance + await vault.sync() + await updateOracle() + await vault.sync() + + // 5. Vault should no longer have enough collateral to cover claims, pro-rata claim should be enabled + const finalPosition = BigNumber.from('0') + const finalCollateral = BigNumber.from('23959832378187916303296') + const btcFinalPosition = BigNumber.from('0') + const btcFinalCollateral = BigNumber.from('5989958094546979075824') + const finalUnclaimed = BigNumber.from('80000022114229307040353') + expect(await longPosition()).to.equal(finalPosition) + expect(await shortPosition()).to.equal(finalPosition) + expect(await longCollateralInVault()).to.equal(finalCollateral) + expect(await shortCollateralInVault()).to.equal(finalCollateral) + expect(await btcLongPosition()).to.equal(btcFinalPosition) + expect(await btcShortPosition()).to.equal(btcFinalPosition) + expect(await btcLongCollateralInVault()).to.equal(btcFinalCollateral) + expect(await btcShortCollateralInVault()).to.equal(btcFinalCollateral) + expect(await vault.unclaimed(user.address)).to.equal(finalUnclaimed) + expect(await vault.totalUnclaimed()).to.equal(finalUnclaimed) + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + + // 6. Claim should be pro-rated + const initialBalanceOf = await asset.balanceOf(user.address) + await vault.claim(user.address) + expect(await longCollateralInVault()).to.equal(0) + expect(await shortCollateralInVault()).to.equal(0) + expect(await btcLongCollateralInVault()).to.equal(0) + expect(await btcShortCollateralInVault()).to.equal(0) + expect(await vault.unclaimed(user.address)).to.equal(0) + expect(await vault.totalUnclaimed()).to.equal(0) + expect(await asset.balanceOf(user.address)).to.equal( + initialBalanceOf.add(finalCollateral.add(btcFinalCollateral).mul(2)).add(1), + ) + + // 7. Should no longer be able to deposit, vault is closed + await expect(vault.connect(user).deposit(2, user.address)).to.revertedWithCustomError( + vault, + 'BalancedVaultDepositLimitExceeded', + ) + }) + }) + }) +}) diff --git a/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts b/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts index a75e32e9..8038a87c 100644 --- a/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts +++ b/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts @@ -1,9 +1,9 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { utils } from 'ethers' +import { constants, utils } from 'ethers' import { createPayoffDefinition } from '../../../../common/testutil/types' -import { ChainlinkOracle__factory, IController__factory, IProduct } from '../../../types/generated' +import { IController__factory, IProduct, IProduct__factory } from '../../../types/generated' -export interface DeployProductParams extends Partial> { +export interface DeployProductParams extends Partial> { name: string symbol: string owner: SignerWithAddress @@ -18,8 +18,7 @@ export async function deployProductOnMainnetFork({ name, symbol, owner, - baseCurrency, - quoteCurrency, + oracle, short, maintenance, fundingFee, @@ -28,27 +27,23 @@ export async function deployProductOnMainnetFork({ positionFee, makerLimit, utilizationCurve, -}: DeployProductParams): Promise { - const chainlinkFeedRegistry = '0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf' - const oracle = await new ChainlinkOracle__factory(owner).deploy(chainlinkFeedRegistry, baseCurrency, quoteCurrency) - +}: DeployProductParams): Promise { const productInfo: IProduct.ProductInfoStruct = { name: name, symbol: symbol, payoffDefinition: createPayoffDefinition({ short: short }), - oracle: oracle.address, - maintenance: maintenance ?? utils.parseEther('0.5'), - fundingFee: fundingFee ?? utils.parseEther('0.10'), + oracle: oracle ?? constants.AddressZero, + maintenance: maintenance ?? utils.parseEther('0.10'), + fundingFee: fundingFee ?? utils.parseEther('0.00'), makerFee: makerFee ?? utils.parseEther('0.0'), takerFee: takerFee ?? utils.parseEther('0.0'), - positionFee: positionFee ?? utils.parseEther('0.5'), + positionFee: positionFee ?? utils.parseEther('0.0'), makerLimit: makerLimit ?? utils.parseEther('100'), utilizationCurve: utilizationCurve ?? { - // Force a 0.10 rate to make tests simpler - minRate: utils.parseEther('0.10'), - maxRate: utils.parseEther('0.10'), - targetRate: utils.parseEther('0.10'), - targetUtilization: utils.parseEther('1'), + minRate: utils.parseEther('0.02'), + maxRate: utils.parseEther('0.08'), + targetRate: utils.parseEther('0.80'), + targetUtilization: utils.parseEther('0.80'), }, } @@ -61,5 +56,5 @@ export async function deployProductOnMainnetFork({ const productAddress = await controller.connect(owner).callStatic.createProduct(coordinatorId, productInfo) await controller.connect(owner).createProduct(coordinatorId, productInfo) - return productAddress + return IProduct__factory.connect(productAddress, owner) } diff --git a/yarn.lock b/yarn.lock index 4d058bc3..d884cd35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7006,10 +7006,10 @@ hardhat-gas-reporter@^1.0.4: eth-gas-reporter "^0.2.24" sha1 "^1.1.1" -hardhat@^2.12.2: - version "2.12.5" - resolved "https://registry.npmjs.org/hardhat/-/hardhat-2.12.5.tgz" - integrity sha512-f/t7+hLlhsnQZ6LDXyV+8rHGRZFZY1sgFvgrwr9fBjMdGp1Bu6hHq1KXS4/VFZfZcVdL1DAWWEkryinZhqce+A== +hardhat@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.13.0.tgz#d52a0ec9b733a651687e5b1c1b0ee9a11a30f3d0" + integrity sha512-ZlzBOLML1QGlm6JWyVAG8lVTEAoOaVm1in/RU2zoGAnYEoD1Rp4T+ZMvrLNhHaaeS9hfjJ1gJUBfiDr4cx+htQ== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" @@ -7058,7 +7058,7 @@ hardhat@^2.12.2: source-map-support "^0.5.13" stacktrace-parser "^0.1.10" tsort "0.0.1" - undici "^5.4.0" + undici "^5.14.0" uuid "^8.3.2" ws "^7.4.6" From d5792413394ed552c720bc32e9154f5a0054adf3 Mon Sep 17 00:00:00 2001 From: Arjun Rao <2940142+arjun-io@users.noreply.github.com> Date: Sun, 16 Apr 2023 22:38:44 -0400 Subject: [PATCH 06/25] enable yul optimizer for coverage --- packages/perennial-vaults/.solcover.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 packages/perennial-vaults/.solcover.js diff --git a/packages/perennial-vaults/.solcover.js b/packages/perennial-vaults/.solcover.js new file mode 100644 index 00000000..af241901 --- /dev/null +++ b/packages/perennial-vaults/.solcover.js @@ -0,0 +1,3 @@ +module.exports = { + configureYulOptimizer: true, +} From bdf6dfe7218993a6b4994c48db6e5251bf6de459 Mon Sep 17 00:00:00 2001 From: Arjun Rao <2940142+arjun-io@users.noreply.github.com> Date: Mon, 17 Apr 2023 10:41:57 -0400 Subject: [PATCH 07/25] increase test timeout --- packages/common/hardhat.default.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/hardhat.default.config.ts b/packages/common/hardhat.default.config.ts index 1a928132..a66c99e3 100644 --- a/packages/common/hardhat.default.config.ts +++ b/packages/common/hardhat.default.config.ts @@ -188,7 +188,7 @@ export default function defaultConfig({ parallel: MOCHA_PARALLEL, reporter: MOCHA_REPORTER, slow: 1000, - timeout: 180000, + timeout: 240000, }, contractSizer: { alphaSort: true, From 4c6b0b301e3ecdd24e0630477d5c5a1b34e81d42 Mon Sep 17 00:00:00 2001 From: Arjun Rao <2940142+arjun-io@users.noreply.github.com> Date: Wed, 19 Apr 2023 10:32:41 -0400 Subject: [PATCH 08/25] test timeout --- packages/common/hardhat.default.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/hardhat.default.config.ts b/packages/common/hardhat.default.config.ts index a66c99e3..ee272457 100644 --- a/packages/common/hardhat.default.config.ts +++ b/packages/common/hardhat.default.config.ts @@ -188,7 +188,7 @@ export default function defaultConfig({ parallel: MOCHA_PARALLEL, reporter: MOCHA_REPORTER, slow: 1000, - timeout: 240000, + timeout: 2400000, }, contractSizer: { alphaSort: true, From 210b793ccff11ec6e7389d59679264ffa8bf0f3c Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:32:31 -0400 Subject: [PATCH 09/25] Multi-Asset Upgrades Verification Tests (#165) * Multi-Asset Upgrades Verification Tests * move setupTokenHolders to shared --- packages/common/testutil/impersonate.ts | 39 +++- packages/common/testutil/oracle.ts | 60 ++++++ packages/perennial-vaults/package.json | 2 +- .../multiAssetUpgrades.test.ts | 183 ++++++++++++++++++ .../verifyPVA.test.ts | 12 +- .../verifyPVB.test.ts | 3 +- .../verification/shared/actions.shared.ts | 73 +++++++ .../test/integration/helpers/setupHelpers.ts | 38 +--- .../shared/opensPosition.shared.ts | 56 +----- 9 files changed, 372 insertions(+), 94 deletions(-) create mode 100644 packages/common/testutil/oracle.ts create mode 100644 packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/multiAssetUpgrades.test.ts rename packages/perennial-vaults/test/verification/arbitrum/{PerennialVaultAlpha => PerennialVaults}/verifyPVA.test.ts (88%) rename packages/perennial-vaults/test/verification/arbitrum/{PerennialVaultAlpha => PerennialVaults}/verifyPVB.test.ts (95%) create mode 100644 packages/perennial-vaults/test/verification/shared/actions.shared.ts diff --git a/packages/common/testutil/impersonate.ts b/packages/common/testutil/impersonate.ts index 5bddc2d2..55c88b70 100644 --- a/packages/common/testutil/impersonate.ts +++ b/packages/common/testutil/impersonate.ts @@ -1,8 +1,17 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { BigNumber, BigNumberish } from 'ethers' +import { BigNumber, BigNumberish, constants, Contract, utils } from 'ethers' import HRE from 'hardhat' const { ethers } = HRE +export const DSU_HOLDER = { + mainnet: '0x0B663CeaCEF01f2f88EB7451C70Aa069f19dB997', + arbitrum: '', +} +export const USDC_HOLDER = { + mainnet: '0x0A59649758aa4d66E25f08Dd01271e891fe52199', + arbitrum: '0x8b8149dd385955dc1ce77a4be7700ccd6a212e65', +} + export async function impersonate(address: string): Promise { await HRE.network.provider.request({ method: 'hardhat_impersonateAccount', @@ -14,7 +23,8 @@ export async function impersonate(address: string): Promise { export async function impersonateWithBalance(address: string, balance: BigNumberish): Promise { await HRE.network.provider.request({ method: 'hardhat_setBalance', - params: [address, BigNumber.from(balance).toHexString()], + // Replace is necessary because leading 0s are not allowed + params: [address, BigNumber.from(balance).toHexString().replace('0x0', '0x')], }) await HRE.network.provider.request({ method: 'hardhat_impersonateAccount', @@ -22,3 +32,28 @@ export async function impersonateWithBalance(address: string, balance: BigNumber }) return ethers.getSigner(address) } + +export async function setupTokenHolders( + dsu: Contract, + usdc: Contract, + reserve: Contract, + users: SignerWithAddress[], + network: 'mainnet' | 'arbitrum' = 'mainnet', +): Promise<{ dsuHolder: SignerWithAddress; usdcHolder: SignerWithAddress }> { + const usdcHolderAddress = USDC_HOLDER[network] + const dsuHolderAddress = DSU_HOLDER[network] || usdcHolderAddress + const usdcHolder = await impersonateWithBalance(usdcHolderAddress, utils.parseEther('10')) + const dsuHolder = await impersonateWithBalance(dsuHolderAddress, utils.parseEther('10')) + + await usdc.connect(usdcHolder).approve(reserve.address, constants.MaxUint256) + await reserve.connect(usdcHolder).mint(utils.parseEther('1000000')) + await dsu.connect(usdcHolder).transfer(dsuHolder.address, utils.parseEther('1000000')) + + await Promise.all( + users.map(async user => { + await dsu.connect(dsuHolder).transfer(user.address, utils.parseEther('20000')) + }), + ) + + return { dsuHolder, usdcHolder } +} diff --git a/packages/common/testutil/oracle.ts b/packages/common/testutil/oracle.ts new file mode 100644 index 00000000..dbc8415a --- /dev/null +++ b/packages/common/testutil/oracle.ts @@ -0,0 +1,60 @@ +import { utils } from 'ethers' +import HRE from 'hardhat' +import { impersonateWithBalance } from './impersonate' +import { time } from './' + +const { config } = HRE + +const AGGREGATOR_TRANSMITTERS = { + mainnet: { + eth: '0x218b5a7861dbf368d09a84e0dbff6c6ddbf99db8', + arb: '', + }, + arbitrum: { + eth: '0xa82d4edb72dd3d167d00058f2404658f4e9a010a', + arb: '0xbd620be125abf8b569b9a3cc132aad0bcf1ff0e7', + }, +} + +const AGGREGATOR_ADDRESSES = { + mainnet: { + eth: '0x37bc7498f4ff12c19678ee8fe19d713b87f6a9e6', + arb: '', + }, + arbitrum: { + eth: '0x3607e46698d218B3a5Cae44bF381475C0a5e2ca7', + arb: '0x46de66f10343b59bacc37df9b3f67cd0ccc121a3', + }, +} + +const TRANSMIT_DATA = { + mainnet: { + eth: '0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000680000001000001000001010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004600000000000000000000000d02ee3e7b93bbe024d583e46d7fe54450000637e0307121618030b0a0f1017131b060d020e051115141a19080c041c1d09011e00000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000025c233d03400000000000000000000000000000000000000000000000000000025c309f68000000000000000000000000000000000000000000000000000000025c309f68000000000000000000000000000000000000000000000000000000025c326458000000000000000000000000000000000000000000000000000000025c3ba49a600000000000000000000000000000000000000000000000000000025c3ba49a600000000000000000000000000000000000000000000000000000025c45986cc00000000000000000000000000000000000000000000000000000025c497ef5c00000000000000000000000000000000000000000000000000000025c4f9108700000000000000000000000000000000000000000000000000000025c4f9108700000000000000000000000000000000000000000000000000000025c511383000000000000000000000000000000000000000000000000000000025c520054000000000000000000000000000000000000000000000000000000025c55d0e4000000000000000000000000000000000000000000000000000000025c57d1f3c00000000000000000000000000000000000000000000000000000025c5b73c3000000000000000000000000000000000000000000000000000000025c5b7e04000000000000000000000000000000000000000000000000000000025c5bbd01000000000000000000000000000000000000000000000000000000025c5bbd01000000000000000000000000000000000000000000000000000000025c5bbd01000000000000000000000000000000000000000000000000000000025c5c1756000000000000000000000000000000000000000000000000000000025c5ec2ee000000000000000000000000000000000000000000000000000000025c5ec2ee000000000000000000000000000000000000000000000000000000025c5fdd83000000000000000000000000000000000000000000000000000000025c5fecc8000000000000000000000000000000000000000000000000000000025c614294000000000000000000000000000000000000000000000000000000025c6236b8000000000000000000000000000000000000000000000000000000025c62b0ca000000000000000000000000000000000000000000000000000000025c634828000000000000000000000000000000000000000000000000000000025c6bd26a100000000000000000000000000000000000000000000000000000025c6bd26a100000000000000000000000000000000000000000000000000000025c7a0e3c0000000000000000000000000000000000000000000000000000000000000000be32a36813c06b85b453cecedce8105af3096411d564fd0b4ee14059db4f0b248e49f256bdf03b543f515863006b4b92c16a7f2db302c9052d8ee4801ae6e47d18b170ebe26e4c449e55b1e6ab3f6603392ce69e542f62f157c1cfec09e2b17b93856141c589f9de601d08ce30fa6ef8c7df4d58c785890d7fe0837d9545f1bf04fd257fe555d525447f87604a16f8fbcc8991272297eecdc96a76cba6151549571f101c07e62f545c49c8bb05d6a6856b1d573dcfd9e58e6a48db6367683917d356b94be544a874cbe93af7f42c1f08a89b9393a508cc41422ec9769e2876bdfc063974b6c7ae9315e295fec278f69c01fcdf3e048ba66d860582e612b00635e3860623f9102256b875aba7e4d8de31dc57d7e7121b15ecd3c07290afe2e1b6c1c27486bef3e3284ab297d67641695ea054fd2ee239eae4745e33ee3853d8da5c67acffa0be14d639de983403f1f09fa7995711873aa776686e5164f51ad0b9e000000000000000000000000000000000000000000000000000000000000000b1188261048dca9e33490656104b845619cda630c3b7a1d33642a705b66dcd2646ff859db2053ceee6d8f34d07fb196ad628372e96d1bf13d51b81294079073b26d9a910d1bafcc2c07ef4768856b1c83d49a726399c558314429367aa036f225422d25aa494ab5536dc12376ede011d45b50978ce98a972e46c7f09793075b8579190b05c91e5cac0aa3dbd12dad6b3a26550ba737f55943afb27a63ef28f2076231cb780dc73d689fcf772ef8c7d26ce4f8c01d8b6c388763fe539b1154e1b043c37beb5c62528e4b00dae076552fde6c8108d871e8ec0da70d3d5a423581ed7b102ca6bdb87a027bc6343ecce71fbf56c5f39edbe9c060ad354468943f8fa825208f17c7d83e5b064ae0aa5940f797e30cd2a4da9991fd3f936083fa15c50455ba7c245aba4860ee72fe5d1075b5be7dd3d0cf9d404a80a30744707d8009c66032ccf98302b5ae19d5824f5c7903ca6808aab80d1e9361bdff1ab8def38ae4', + arb: '', + }, + arbitrum: { + eth: '0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000300000101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000f6d9397093865a569a3b827fbe021b4e0003a6060606010207000403050809000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000002ffb63bac00000000000000000000000000000000000000000000000000000002ffee6c7000000000000000000000000000000000000000000000000000000002ffee6c700000000000000000000000000000000000000000000000000000000300027364000000000000000000000000000000000000000000000000000000030014158d000000000000000000000000000000000000000000000000000000030014158d0000000000000000000000000000000000000000000000000000000300176e7c00000000000000000000000000000000000000000000000000000003001e40eac000000000000000000000000000000000000000000000000000000300303a2400000000000000000000000000000000000000000000000000000003004258d0000000000000000000000000000000000000000000000000000000000000000040cd9d57b3f26761b5606b3dffb11327300a64b017143239fbec97a514e615254bd20cb47ded3e708594af8b42f422e65622f09a551312a4186a3e5df8edf1c46ae2a15ac5b48fb42243b05b34366b9b1ccf1aaf3e9fe06f7e0ebf26e23ead40061f5a96d7cb636119a14f760443c0ba5b3f3cb0474c3f835da94b344af39be9f000000000000000000000000000000000000000000000000000000000000000452ccc64510100a8f36a5d8d026e995cb3c7086747405765595c7faab3fd2e1375b79c638774f4d28803fcb17462769837adc904ba76e3926422454190e6d0d9f4037f8a08da1704d4e09907ec759934729c7b6fdcb8f56943fefad0027438256322753f7b5b143d4e7d4cf800ef801fd87eca663d43b3cbcdf8a07b26c30ceca', + arb: '0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000300010100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000009b7760208df7ee5e7a4e980008eecbb0000275f0109020005040706010308000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000008c554b00000000000000000000000000000000000000000000000000000000008c5f0f00000000000000000000000000000000000000000000000000000000008c758000000000000000000000000000000000000000000000000000000000008c758000000000000000000000000000000000000000000000000000000000008c9b5c80000000000000000000000000000000000000000000000000000000008c9b5c80000000000000000000000000000000000000000000000000000000008c9d8f00000000000000000000000000000000000000000000000000000000008c9e8900000000000000000000000000000000000000000000000000000000008c9e8900000000000000000000000000000000000000000000000000000000008cd11a70000000000000000000000000000000000000000000000000000000000000004c706b98db35a5790f5598543b84a7773c8d535043bb22cb00e73deda0f98cee5781a23e59a2369009c06a20565e768332c7b014eab7373b1a5bd4afccb017b36cd8f51dcfc494f0cf9ee05b5e16d0d1e176aa84aefb706dfaa0b11fb2f089f07467a1d8e02711c400f333f4aced0cb0191c1c0e885c64d5e0d5fb8e872c6bde4000000000000000000000000000000000000000000000000000000000000000463a1fd7cbbee40fd0ea99d2557e4931c978355e4b9383f686af5f10e3e50c8a035062d34074c560f1111f717b428bfc04d24b2dd9e831d8869c76bcf5ea0eb64091458055f60e259b992d71d338d1089f0c6803ab5ea51c96686a1403a579ade61e5966ce7f6d05b17b32ebfe0b94beaac0e95c928dad0e244e86431ae34c1bb', + }, +} + +export async function pushPrice( + network: 'mainnet' | 'arbitrum' = 'mainnet', + asset: 'eth' | 'arb' = 'eth', +): Promise { + if (!AGGREGATOR_TRANSMITTERS[network][asset]) { + throw 'Invalid Network/Asset pair' + } + + const transmitterSigner = await impersonateWithBalance( + AGGREGATOR_TRANSMITTERS[network][asset], + utils.parseEther('10'), + ) + + // Push a new price version to the aggregator + await transmitterSigner.sendTransaction({ + to: AGGREGATOR_ADDRESSES[network][asset], + value: 0, + data: TRANSMIT_DATA[network][asset], + }) +} diff --git a/packages/perennial-vaults/package.json b/packages/perennial-vaults/package.json index 58adc1ab..067e9419 100644 --- a/packages/perennial-vaults/package.json +++ b/packages/perennial-vaults/package.json @@ -18,7 +18,7 @@ "gasReport": "REPORT_GAS=true yarn test:integration", "test": "hardhat test test/unit/**/*", "test:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat test test/integration/**/*", - "test:verification:arbitrum": "FORK_ENABLED=true FORK_NETWORK=arbitrum FORK_BLOCK_NUMBER=75050457 FORK_USE_REAL_DEPLOYS=true hardhat test test/verification/arbitrum/**/*", + "test:verification:arbitrum": "FORK_ENABLED=true FORK_NETWORK=arbitrum FORK_BLOCK_NUMBER=80132631 FORK_USE_REAL_DEPLOYS=true hardhat test test/verification/arbitrum/**/*", "coverage": "hardhat coverage --testfiles 'test/unit/**/*'", "coverage:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat coverage --testfiles 'test/integration/*'", "lint": "eslint --fix --ext '.ts,.js' ./ && solhint 'contracts/**/*.sol' --fix", diff --git a/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/multiAssetUpgrades.test.ts b/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/multiAssetUpgrades.test.ts new file mode 100644 index 00000000..911b0b41 --- /dev/null +++ b/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/multiAssetUpgrades.test.ts @@ -0,0 +1,183 @@ +import { expect } from 'chai' +import HRE from 'hardhat' +import { utils } from 'ethers' +import { Deployment } from 'hardhat-deploy/types' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { + BalancedVault, + BalancedVault__factory, + ICollateral__factory, + ProxyAdmin, + ProxyAdmin__factory, +} from '../../../../types/generated' +import { impersonate, time } from '../../../../../common/testutil' +import { expectVaultDeposit, expectVaultRedeemAndClaim } from '../../shared/actions.shared' + +const { ethers, config } = HRE + +describe('Vault - Perennial Vaults - Multi-Asset Upgrade', () => { + let signer: SignerWithAddress + let deployments: { [name: string]: Deployment } + let proxyAdmin: ProxyAdmin + let adminOwner: SignerWithAddress + let vault: BalancedVault + let vaultDepositor: SignerWithAddress + + beforeEach(async () => { + await time.reset(config) + + deployments = await HRE.deployments.all() + ;[signer] = await ethers.getSigners() + + proxyAdmin = ProxyAdmin__factory.connect(deployments['ProxyAdmin'].address, signer) + adminOwner = await impersonate.impersonateWithBalance(await proxyAdmin.callStatic.owner(), utils.parseEther('1')) + vault = BalancedVault__factory.connect(deployments['PerennialVaultAlpha_Proxy'].address, signer) + vaultDepositor = await impersonate.impersonate('0xa045f488db8d754754fd89d0675725ef00e63264') + }) + + it('upgrades to the new multi-asset vault and keeps state', async () => { + const prevVault = new ethers.Contract(vault.address, deployments['PerennialVaultAlpha_Impl'].abi, signer) + const [long, short, totalSupply, totalAssets, totalUnclaimed, vaultBalances] = await Promise.all([ + prevVault.long(), + prevVault.short(), + prevVault.totalSupply(), + prevVault.totalAssets(), + prevVault.totalUnclaimed(), + getVaultUsers(vault), + ]) + + const newImpl = await new BalancedVault__factory(signer).deploy( + await vault.asset(), + await vault.controller(), + await vault.targetLeverage(), + await vault.maxCollateral(), + [{ long, short, weight: utils.parseEther('1') }], + ) + + await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImpl.address) + await vault.initialize('PerennialVaultAlpha') + + expect(await proxyAdmin.callStatic.getProxyImplementation(vault.address)).to.equal(newImpl.address) + expect((await vault.markets(0)).long).to.equal(long) + expect((await vault.markets(0)).short).to.equal(short) + expect(await vault.totalAssets()).to.equal(totalAssets) + expect(await vault.totalUnclaimed()).to.equal(totalUnclaimed) + expect(await vault.totalSupply()).to.equal(totalSupply) + for (const { user, balance } of vaultBalances) { + expect(await vault.balanceOf(user)).to.equal(balance) + } + }) + + context('after upgraded', () => { + beforeEach(async () => { + const prevVault = new ethers.Contract(vault.address, deployments['PerennialVaultAlpha_Impl'].abi, signer) + const [long, short] = await Promise.all([prevVault.long(), prevVault.short()]) + + const newImpl = await new BalancedVault__factory(signer).deploy( + await vault.asset(), + await vault.controller(), + await vault.targetLeverage(), + await vault.maxCollateral(), + [{ long, short, weight: utils.parseEther('1') }], + ) + await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImpl.address) + }) + + it('deposits', async () => { + await expectVaultDeposit(vault, signer, deployments, 'arbitrum', ['eth']) + }) + + it('redeems and claims', async () => { + await expectVaultRedeemAndClaim(vault, signer, vaultDepositor, deployments, 'arbitrum', ['eth']) + }) + + it('updates to the new multi-asset vault with multiple markets', async () => { + const arbLong = deployments['Product_LongArbitrum'].address + const arbShort = deployments['Product_ShortArbitrum'].address + const [market0, totalAssets, totalUnclaimed, totalSupply, vaultBalances] = await Promise.all([ + vault.markets(0), + vault.totalAssets(), + vault.totalUnclaimed(), + vault.totalSupply(), + getVaultUsers(vault), + ]) + + const newImplMulti = await new BalancedVault__factory(signer).deploy( + await vault.asset(), + await vault.controller(), + await vault.targetLeverage(), + await vault.maxCollateral(), + [ + { long: market0.long, short: market0.short, weight: utils.parseEther('1') }, + { long: arbLong, short: arbShort, weight: utils.parseEther('0.1') }, + ], + ) + await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImplMulti.address) + await vault.initialize('PerennialVaultAlpha') + expect(await proxyAdmin.callStatic.getProxyImplementation(vault.address)).to.equal(newImplMulti.address) + + expect((await vault.markets(0)).long).to.equal(market0.long) + expect((await vault.markets(0)).short).to.equal(market0.short) + expect((await vault.markets(1)).long).to.equal(arbLong) + expect((await vault.markets(1)).short).to.equal(arbShort) + + expect(await vault.totalAssets()).to.equal(totalAssets) + expect(await vault.totalUnclaimed()).to.equal(totalUnclaimed) + expect(await vault.totalSupply()).to.equal(totalSupply) + for (const { user, balance } of vaultBalances) { + expect(await vault.balanceOf(user)).to.equal(balance) + } + }) + + context('after multi-market upgrade', () => { + beforeEach(async () => { + const arbLong = deployments['Product_LongArbitrum'].address + const arbShort = deployments['Product_ShortArbitrum'].address + const market0 = await vault.markets(0) + const newImplMulti = await new BalancedVault__factory(signer).deploy( + await vault.asset(), + await vault.controller(), + await vault.targetLeverage(), + await vault.maxCollateral(), + [ + { long: market0.long, short: market0.short, weight: utils.parseEther('0.5') }, + { long: arbLong, short: arbShort, weight: utils.parseEther('0.5') }, + ], + ) + await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImplMulti.address) + await vault.initialize('PerennialVaultAlpha') + }) + + it('deposits', async () => { + const collateral = ICollateral__factory.connect(deployments['Collateral_Proxy'].address, signer) + const market1 = await vault.markets(1) + const [longCollateral, shortCollateral] = await Promise.all([ + collateral['collateral(address,address)'](vault.address, market1.long), + collateral['collateral(address,address)'](vault.address, market1.short), + ]) + expect(longCollateral).to.equal(0) + expect(shortCollateral).to.equal(0) + + await expectVaultDeposit(vault, signer, deployments, 'arbitrum', ['eth', 'arb']) + + expect(await collateral['collateral(address,address)'](vault.address, market1.long)).to.be.gt(0) + expect(await collateral['collateral(address,address)'](vault.address, market1.short)).to.be.gt(0) + }) + + it('redeems and claims', async () => { + await expectVaultRedeemAndClaim(vault, signer, vaultDepositor, deployments, 'arbitrum', ['eth', 'arb']) + }) + }) + }) +}) + +const getVaultUsers = async (vault: BalancedVault) => { + const currentBlock = await ethers.provider.getBlockNumber() + const vaultDeposits = await vault.queryFilter(vault.filters.Deposit(), currentBlock - 500000, currentBlock) + const vaultUsers = Array.from(new Set(vaultDeposits.map(e => e.args.account))) + const vaultBalances = await Promise.all( + vaultUsers.map(async user => ({ user, balance: await vault.balanceOf(user) })), + ) + + return vaultBalances +} diff --git a/packages/perennial-vaults/test/verification/arbitrum/PerennialVaultAlpha/verifyPVA.test.ts b/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/verifyPVA.test.ts similarity index 88% rename from packages/perennial-vaults/test/verification/arbitrum/PerennialVaultAlpha/verifyPVA.test.ts rename to packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/verifyPVA.test.ts index 1aa9d37a..212eb79c 100644 --- a/packages/perennial-vaults/test/verification/arbitrum/PerennialVaultAlpha/verifyPVA.test.ts +++ b/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/verifyPVA.test.ts @@ -11,8 +11,10 @@ import { ProxyAdmin, ProxyAdmin__factory, } from '../../../../types/generated' +import { impersonate, time } from '../../../../../common/testutil' +import { expectVaultDeposit, expectVaultRedeemAndClaim } from '../../shared/actions.shared' -const { ethers } = HRE +const { ethers, config } = HRE describe('Vault - Perennial Vault Alpha - Arbitrum Verification', () => { let signer: SignerWithAddress @@ -22,15 +24,18 @@ describe('Vault - Perennial Vault Alpha - Arbitrum Verification', () => { let vault: BalancedVault beforeEach(async () => { - ;[signer] = await ethers.getSigners() + await time.reset(config) + deployments = await HRE.deployments.all() + ;[signer] = await ethers.getSigners() + controller = IController__factory.connect(deployments['Controller_Proxy'].address, signer) proxyAdmin = ProxyAdmin__factory.connect(deployments['ProxyAdmin'].address, signer) vault = BalancedVault__factory.connect(deployments['PerennialVaultAlpha_Proxy'].address, signer) }) it('is already initialized', async () => { - await expect(vault.callStatic.initialize('PerennialVaultAlpha', 'PVA')).to.be.revertedWithCustomError( + await expect(vault.callStatic.initialize('PerennialVaultAlpha')).to.be.revertedWithCustomError( vault, 'UInitializableAlreadyInitializedError', ) @@ -41,7 +46,6 @@ describe('Vault - Perennial Vault Alpha - Arbitrum Verification', () => { expect(await vault.collateral()).to.equal(await controller.collateral()) expect(await vault.name()).to.equal('Perennial Vault Alpha') - expect(await vault.symbol()).to.equal('PVA') expect(await vault.maxCollateral()).to.equal(utils.parseEther('1000000')) expect(await vault.targetLeverage()).to.equal(utils.parseEther('3')) expect(await vault.asset()).to.equal(deployments['DSU'].address) diff --git a/packages/perennial-vaults/test/verification/arbitrum/PerennialVaultAlpha/verifyPVB.test.ts b/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/verifyPVB.test.ts similarity index 95% rename from packages/perennial-vaults/test/verification/arbitrum/PerennialVaultAlpha/verifyPVB.test.ts rename to packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/verifyPVB.test.ts index d1bd6e96..90024509 100644 --- a/packages/perennial-vaults/test/verification/arbitrum/PerennialVaultAlpha/verifyPVB.test.ts +++ b/packages/perennial-vaults/test/verification/arbitrum/PerennialVaults/verifyPVB.test.ts @@ -30,7 +30,7 @@ describe('Vault - Perennial Vault Bravo - Arbitrum Verification', () => { }) it('is already initialized', async () => { - await expect(vault.callStatic.initialize('PerennialVaultBravo', 'PVB')).to.be.revertedWithCustomError( + await expect(vault.callStatic.initialize('PerennialVaultBravo')).to.be.revertedWithCustomError( vault, 'UInitializableAlreadyInitializedError', ) @@ -41,7 +41,6 @@ describe('Vault - Perennial Vault Bravo - Arbitrum Verification', () => { expect(await vault.collateral()).to.equal(await controller.collateral()) expect(await vault.name()).to.equal('Perennial Vault Bravo') - expect(await vault.symbol()).to.equal('PVB') expect(await vault.maxCollateral()).to.equal(utils.parseEther('500000')) expect(await vault.targetLeverage()).to.equal(utils.parseEther('2')) expect(await vault.asset()).to.equal(deployments['DSU'].address) diff --git a/packages/perennial-vaults/test/verification/shared/actions.shared.ts b/packages/perennial-vaults/test/verification/shared/actions.shared.ts new file mode 100644 index 00000000..1ac18c63 --- /dev/null +++ b/packages/perennial-vaults/test/verification/shared/actions.shared.ts @@ -0,0 +1,73 @@ +import { expect } from 'chai' +import { constants, utils } from 'ethers' +import HRE from 'hardhat' +import { pushPrice } from '../../../../common/testutil/oracle' +import { BalancedVault, IEmptySetReserve__factory, IERC20Metadata__factory } from '../../../types/generated' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { Deployment } from 'hardhat-deploy/types' +import { setupTokenHolders } from '../../../../common/testutil/impersonate' + +const { ethers } = HRE + +export async function expectVaultDeposit( + vault: BalancedVault, + signer: SignerWithAddress, + deployments: { [name: string]: Deployment }, + network: 'mainnet' | 'arbitrum' = 'mainnet', + assets: Array<'eth' | 'arb'> = ['eth'], +): Promise { + const dsu = IERC20Metadata__factory.connect(deployments['DSU'].address, signer) + const usdc = IERC20Metadata__factory.connect(deployments['USDC'].address, signer) + const reserve = IEmptySetReserve__factory.connect(deployments['EmptysetReserve'].address, signer) + + const [, userA, userB] = await ethers.getSigners() + const { dsuHolder } = await setupTokenHolders(dsu, usdc, reserve, [], network) + + await dsu.connect(dsuHolder).approve(vault.address, constants.MaxUint256) + await vault.connect(dsuHolder).deposit(utils.parseEther('1000'), userA.address) + await vault.connect(dsuHolder).deposit(utils.parseEther('1000'), userB.address) + + const currentEpoch = await vault.currentEpoch() + + // Push new oracle price + await Promise.all(assets.map(asset => pushPrice(network, asset))) + + await vault.sync() + const nextEpoch = await vault.currentEpoch() + + expect(nextEpoch).to.equal(currentEpoch.add(1)) + const expectedBalance = await vault.convertToShares(utils.parseEther('1000')) + expect(await vault.balanceOf(userA.address)).to.equal(expectedBalance) + expect(await vault.balanceOf(userB.address)).to.equal(expectedBalance) +} + +export async function expectVaultRedeemAndClaim( + vault: BalancedVault, + signer: SignerWithAddress, + user: SignerWithAddress, + deployments: { [name: string]: Deployment }, + network: 'mainnet' | 'arbitrum' = 'mainnet', + assets: Array<'eth' | 'arb'> = ['eth'], +): Promise { + const dsu = IERC20Metadata__factory.connect(deployments['DSU'].address, signer) + + const currentEpoch = await vault.currentEpoch() + const currentDSUBalance = await dsu.balanceOf(user.address) + const currentBalance = await vault.balanceOf(user.address) + await vault.connect(user).redeem(currentBalance, user.address) + + // Push new oracle price + await Promise.all(assets.map(asset => pushPrice(network, asset))) + + await vault.sync() + const nextEpoch = await vault.currentEpoch() + + expect(nextEpoch).to.equal(currentEpoch.add(1)) + expect(await vault.balanceOf(user.address)).to.equal(0) + + const expectedDSUReceived = await vault.convertToAssets(currentBalance) + expect(await vault.unclaimed(user.address)).to.equal(expectedDSUReceived) + + await vault.connect(user).claim(user.address) + expect(await dsu.balanceOf(user.address)).to.equal(currentDSUBalance.add(expectedDSUReceived)) +} diff --git a/packages/perennial/test/integration/helpers/setupHelpers.ts b/packages/perennial/test/integration/helpers/setupHelpers.ts index 4287eb8b..b7a32e11 100644 --- a/packages/perennial/test/integration/helpers/setupHelpers.ts +++ b/packages/perennial/test/integration/helpers/setupHelpers.ts @@ -1,9 +1,9 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import HRE from 'hardhat' -import { BigNumber, constants, utils } from 'ethers' +import { BigNumber, utils } from 'ethers' import { CHAINLINK_CUSTOM_CURRENCIES, buildChainlinkRoundId } from '@equilibria/perennial-oracle/util' -import { time, impersonate } from '../../../../common/testutil' +import { time } from '../../../../common/testutil' import { Collateral, Controller, @@ -40,19 +40,12 @@ import { } from '../../../types/generated' import { ChainlinkContext } from './chainlinkHelpers' import { createPayoffDefinition } from '../../../../common/testutil/types' +import { setupTokenHolders } from '../../../../common/testutil/impersonate' const { config, deployments, ethers } = HRE export const INITIAL_PHASE_ID = 1 export const INITIAL_AGGREGATOR_ROUND_ID = 10000 export const INITIAL_VERSION = INITIAL_AGGREGATOR_ROUND_ID - 7528 // registry's phase 1 starts at aggregatorRoundID 7528 -export const DSU_HOLDER = { - mainnet: '0x0B663CeaCEF01f2f88EB7451C70Aa069f19dB997', - arbitrum: '', -} -export const USDC_HOLDER = { - mainnet: '0x0A59649758aa4d66E25f08Dd01271e891fe52199', - arbitrum: '0x8b8149dd385955dc1ce77a4be7700ccd6a212e65', -} export interface InstanceVars { owner: SignerWithAddress @@ -307,28 +300,3 @@ export async function depositTo( await dsu.connect(user).approve(collateral.address, position) await collateral.connect(user).depositTo(user.address, product.address, position) } - -export async function setupTokenHolders( - dsu: IERC20Metadata, - usdc: IERC20Metadata, - reserve: IEmptySetReserve, - users: SignerWithAddress[], - network: 'mainnet' | 'arbitrum' = 'mainnet', -): Promise<{ dsuHolder: SignerWithAddress; usdcHolder: SignerWithAddress }> { - const usdcHolderAddress = USDC_HOLDER[network] - const dsuHolderAddress = DSU_HOLDER[network] || usdcHolderAddress - const usdcHolder = await impersonate.impersonateWithBalance(usdcHolderAddress, utils.parseEther('10')) - const dsuHolder = await impersonate.impersonateWithBalance(dsuHolderAddress, utils.parseEther('10')) - - await usdc.connect(usdcHolder).approve(reserve.address, constants.MaxUint256) - await reserve.connect(usdcHolder).mint(utils.parseEther('1000000')) - await dsu.connect(usdcHolder).transfer(dsuHolder.address, utils.parseEther('1000000')) - - await Promise.all( - users.map(async user => { - await dsu.connect(dsuHolder).transfer(user.address, utils.parseEther('20000')) - }), - ) - - return { dsuHolder, usdcHolder } -} diff --git a/packages/perennial/test/verification/shared/opensPosition.shared.ts b/packages/perennial/test/verification/shared/opensPosition.shared.ts index fc510538..1200e6b1 100644 --- a/packages/perennial/test/verification/shared/opensPosition.shared.ts +++ b/packages/perennial/test/verification/shared/opensPosition.shared.ts @@ -1,7 +1,7 @@ -import { expect, util } from 'chai' +import { expect } from 'chai' import { utils, constants } from 'ethers' import HRE from 'hardhat' -import { impersonateWithBalance } from '../../../../common/testutil/impersonate' +import { pushPrice } from '../../../../common/testutil/oracle' import { expectPositionEq } from '../../../../common/testutil/types' import { Collateral__factory, @@ -16,39 +16,6 @@ import { time } from '../../../../common/testutil' const { ethers, config } = HRE -const AGGREGATOR_TRANSMITTERS = { - mainnet: { - eth: '0x218b5a7861dbf368d09a84e0dbff6c6ddbf99db8', - arb: '', - }, - arbitrum: { - eth: '0xa82d4edb72dd3d167d00058f2404658f4e9a010a', - arb: '0xbd620be125abf8b569b9a3cc132aad0bcf1ff0e7', - }, -} - -const AGGREGATOR_ADDRESSES = { - mainnet: { - eth: '0x37bc7498f4ff12c19678ee8fe19d713b87f6a9e6', - arb: '', - }, - arbitrum: { - eth: '0x3607e46698d218B3a5Cae44bF381475C0a5e2ca7', - arb: '0x46de66f10343b59bacc37df9b3f67cd0ccc121a3', - }, -} - -const TRANSMIT_DATA = { - mainnet: { - eth: '0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000680000001000001000001010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004600000000000000000000000d02ee3e7b93bbe024d583e46d7fe54450000637e0307121618030b0a0f1017131b060d020e051115141a19080c041c1d09011e00000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000025c233d03400000000000000000000000000000000000000000000000000000025c309f68000000000000000000000000000000000000000000000000000000025c309f68000000000000000000000000000000000000000000000000000000025c326458000000000000000000000000000000000000000000000000000000025c3ba49a600000000000000000000000000000000000000000000000000000025c3ba49a600000000000000000000000000000000000000000000000000000025c45986cc00000000000000000000000000000000000000000000000000000025c497ef5c00000000000000000000000000000000000000000000000000000025c4f9108700000000000000000000000000000000000000000000000000000025c4f9108700000000000000000000000000000000000000000000000000000025c511383000000000000000000000000000000000000000000000000000000025c520054000000000000000000000000000000000000000000000000000000025c55d0e4000000000000000000000000000000000000000000000000000000025c57d1f3c00000000000000000000000000000000000000000000000000000025c5b73c3000000000000000000000000000000000000000000000000000000025c5b7e04000000000000000000000000000000000000000000000000000000025c5bbd01000000000000000000000000000000000000000000000000000000025c5bbd01000000000000000000000000000000000000000000000000000000025c5bbd01000000000000000000000000000000000000000000000000000000025c5c1756000000000000000000000000000000000000000000000000000000025c5ec2ee000000000000000000000000000000000000000000000000000000025c5ec2ee000000000000000000000000000000000000000000000000000000025c5fdd83000000000000000000000000000000000000000000000000000000025c5fecc8000000000000000000000000000000000000000000000000000000025c614294000000000000000000000000000000000000000000000000000000025c6236b8000000000000000000000000000000000000000000000000000000025c62b0ca000000000000000000000000000000000000000000000000000000025c634828000000000000000000000000000000000000000000000000000000025c6bd26a100000000000000000000000000000000000000000000000000000025c6bd26a100000000000000000000000000000000000000000000000000000025c7a0e3c0000000000000000000000000000000000000000000000000000000000000000be32a36813c06b85b453cecedce8105af3096411d564fd0b4ee14059db4f0b248e49f256bdf03b543f515863006b4b92c16a7f2db302c9052d8ee4801ae6e47d18b170ebe26e4c449e55b1e6ab3f6603392ce69e542f62f157c1cfec09e2b17b93856141c589f9de601d08ce30fa6ef8c7df4d58c785890d7fe0837d9545f1bf04fd257fe555d525447f87604a16f8fbcc8991272297eecdc96a76cba6151549571f101c07e62f545c49c8bb05d6a6856b1d573dcfd9e58e6a48db6367683917d356b94be544a874cbe93af7f42c1f08a89b9393a508cc41422ec9769e2876bdfc063974b6c7ae9315e295fec278f69c01fcdf3e048ba66d860582e612b00635e3860623f9102256b875aba7e4d8de31dc57d7e7121b15ecd3c07290afe2e1b6c1c27486bef3e3284ab297d67641695ea054fd2ee239eae4745e33ee3853d8da5c67acffa0be14d639de983403f1f09fa7995711873aa776686e5164f51ad0b9e000000000000000000000000000000000000000000000000000000000000000b1188261048dca9e33490656104b845619cda630c3b7a1d33642a705b66dcd2646ff859db2053ceee6d8f34d07fb196ad628372e96d1bf13d51b81294079073b26d9a910d1bafcc2c07ef4768856b1c83d49a726399c558314429367aa036f225422d25aa494ab5536dc12376ede011d45b50978ce98a972e46c7f09793075b8579190b05c91e5cac0aa3dbd12dad6b3a26550ba737f55943afb27a63ef28f2076231cb780dc73d689fcf772ef8c7d26ce4f8c01d8b6c388763fe539b1154e1b043c37beb5c62528e4b00dae076552fde6c8108d871e8ec0da70d3d5a423581ed7b102ca6bdb87a027bc6343ecce71fbf56c5f39edbe9c060ad354468943f8fa825208f17c7d83e5b064ae0aa5940f797e30cd2a4da9991fd3f936083fa15c50455ba7c245aba4860ee72fe5d1075b5be7dd3d0cf9d404a80a30744707d8009c66032ccf98302b5ae19d5824f5c7903ca6808aab80d1e9361bdff1ab8def38ae4', - arb: '', - }, - arbitrum: { - eth: '0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000300010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000f6d9397093865a569a3b827fbe021b4e000343360507050800030601040209000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000002782f0e5700000000000000000000000000000000000000000000000000000002783ffe89300000000000000000000000000000000000000000000000000000027847b41ad0000000000000000000000000000000000000000000000000000002784b35dc000000000000000000000000000000000000000000000000000000027855a1d4000000000000000000000000000000000000000000000000000000027880cba2000000000000000000000000000000000000000000000000000000027886bf12000000000000000000000000000000000000000000000000000000027899002a8000000000000000000000000000000000000000000000000000000278ad5ec40000000000000000000000000000000000000000000000000000000278c089ddb000000000000000000000000000000000000000000000000000000000000000420616b3fdd76eb1e59b94f175754040c9723e30a56256d11239ff2366e82377777f381df454787541124925bb52981cdf59eec0e3514648ff280feab97ca96d696cc2efd8c8d2f5988cce81749365bc5828e38feef44470f957d69316741ba10f936ec0640a5e0d400826cc685fd0ef7d851016f53924f087bf75becc768627200000000000000000000000000000000000000000000000000000000000000047acf29ec113d44b5a76dbb59b30dab94c1023e2827d347cc48d42075b478243c68b909e121058f4de64cf46214384df9996dfa063835314c7b8c3deaa945de1b563867b9e63802ef3b6b0777f5d25e2cb9133652b960d07076d47c43586e2c29559cb20f945debfe633804692a906eb797cbf1c0364230c93f782a63e5b647a3', - arb: '0xc9807539000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000300000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000009b7760208df7ee5e7a4e980008eecbb000009eb0407060102090408050003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000007447ada00000000000000000000000000000000000000000000000000000000074532e80000000000000000000000000000000000000000000000000000000007469223000000000000000000000000000000000000000000000000000000000747117f000000000000000000000000000000000000000000000000000000000747117f0000000000000000000000000000000000000000000000000000000007471de50000000000000000000000000000000000000000000000000000000007471de5000000000000000000000000000000000000000000000000000000000747a5a5000000000000000000000000000000000000000000000000000000000747f5a2000000000000000000000000000000000000000000000000000000000748921500000000000000000000000000000000000000000000000000000000000000045b3169e2bc490a415e0f674c9a20d895131c9e63c9eb727ee564da0206660bcd00187a0a6819243372a8755ade7fed98272a391d7bbd21dd7525ad10763416a4794a5fd91cf11ca43680feb6521a932e8cee1a0995a0a498c2589d6283ae1e0e58c68577a1fc23e7c587830c8b61764c8272b87bf17965f3d09e36f307b5bf0e00000000000000000000000000000000000000000000000000000000000000042036a45ce8cfb08d0e95e7ee832d145eec9afc8daf4f00c4f6729dcc94a536b25a020ea93e62b321651372234d195754fcef38da46815e9944b80a76102ff2f512966f4389a3cb21d62618e17d5f3ace236a724723aaed7076bec5b7e0d769531b01b7f417682e841ced31a5fa2746c34983c62d8d6c08e78d307a845b3b7911', - }, -} - const POSITION = utils.parseEther('0.01') export default async function opensPositions( @@ -60,15 +27,6 @@ export default async function opensPositions( ): Promise { await time.reset(config) - if (!AGGREGATOR_TRANSMITTERS[network][asset]) { - throw 'Invalid Network/Asset pair' - } - - const transmitterSigner = await impersonateWithBalance( - AGGREGATOR_TRANSMITTERS[network][asset], - utils.parseEther('10'), - ) - const collateral = Collateral__factory.connect(deployments['Collateral_Proxy'].address, signer) const dsu = IERC20Metadata__factory.connect(deployments['DSU'].address, signer) const usdc = IERC20Metadata__factory.connect(deployments['USDC'].address, signer) @@ -90,12 +48,10 @@ export default async function opensPositions( const latestVersion = await product['latestVersion()']() const latestPosition = await product.positionAtVersion(latestVersion) - // Push a new price version to the aggregator - await transmitterSigner.sendTransaction({ - to: AGGREGATOR_ADDRESSES[network][asset], - value: 0, - data: TRANSMIT_DATA[network][asset], - }) + + // Push new oracle price + await pushPrice(network, asset) + await expect(product.settle()).to.not.be.reverted const nextVersion = await product['latestVersion()']() From 418ca934be758e665d4afe667b9daff7c10efdd8 Mon Sep 17 00:00:00 2001 From: 0xfennel <117121807+0xfennel@users.noreply.github.com> Date: Mon, 8 May 2023 23:19:03 -0700 Subject: [PATCH 10/25] Change _claimProduct param to calldata (#172) --- packages/perennial/contracts/incentivizer/Incentivizer.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/perennial/contracts/incentivizer/Incentivizer.sol b/packages/perennial/contracts/incentivizer/Incentivizer.sol index a87552d4..4e642416 100644 --- a/packages/perennial/contracts/incentivizer/Incentivizer.sol +++ b/packages/perennial/contracts/incentivizer/Incentivizer.sol @@ -179,7 +179,7 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe * @param product Product to claim rewards for * @param programIds Programs to claim rewards for */ - function _claimProduct(address account, IProduct product, uint256[] memory programIds) + function _claimProduct(address account, IProduct product, uint256[] calldata programIds) private isProduct(product) notPaused From 388fb5a41fae105cb3b50206f1d4ef5ff269d58d Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 9 May 2023 12:23:42 -0400 Subject: [PATCH 11/25] Remove negative price comment from Oracles (#173) --- packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol | 1 - packages/perennial-oracle/contracts/ChainlinkOracle.sol | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol index 73b6e869..677848fd 100644 --- a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol @@ -10,7 +10,6 @@ import "./types/ChainlinkAggregator.sol"; * @notice Chainlink feed implementation of the IOracle interface. * @dev One instance per Chainlink price feed should be deployed. Multiple products may use the same * ChainlinkOracle instance if their payoff functions are based on the same underlying oracle. - * This implementation only supports non-negative prices. */ contract ChainlinkFeedOracle is IOracleProvider { diff --git a/packages/perennial-oracle/contracts/ChainlinkOracle.sol b/packages/perennial-oracle/contracts/ChainlinkOracle.sol index 22234306..6c98194b 100644 --- a/packages/perennial-oracle/contracts/ChainlinkOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkOracle.sol @@ -11,7 +11,6 @@ import "./types/ChainlinkRegistry.sol"; * @notice Chainlink registry implementation of the IOracle interface. * @dev One instance per Chainlink price feed should be deployed. Multiple products may use the same * ChainlinkOracle instance if their payoff functions are based on the same underlying oracle. - * This implementation only supports non-negative prices. */ contract ChainlinkOracle is IOracleProvider { /// @dev Chainlink registry feed address From ec511fd60a5805aaee6ec0875ae65378cc92a499 Mon Sep 17 00:00:00 2001 From: 0xfennel <117121807+0xfennel@users.noreply.github.com> Date: Tue, 9 May 2023 11:08:26 -0700 Subject: [PATCH 12/25] Get rid of extraneous .only (#178) --- .../test/integration/BalancedVault/balancedVaultMulti.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts index b81baeb3..5149b68c 100644 --- a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts @@ -27,7 +27,7 @@ use(smock.matchers) const DSU_MINTER = '0xD05aCe63789cCb35B9cE71d01e4d632a0486Da4B' -describe.only('BalancedVault (Multi-Payoff)', () => { +describe('BalancedVault (Multi-Payoff)', () => { let vault: BalancedVault let asset: IERC20Metadata let oracle: FakeContract From 4f0b1f2498f04ce34a40fb38d5a33a3cf86621f7 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 9 May 2023 14:09:08 -0400 Subject: [PATCH 13/25] Revert if address is not valid product (#177) --- .../contracts/controller/Controller.sol | 4 +++- .../contracts/interfaces/IController.sol | 1 + .../test/unit/controller/Controller.test.ts | 20 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/perennial/contracts/controller/Controller.sol b/packages/perennial/contracts/controller/Controller.sol index 0a390778..3eeff885 100644 --- a/packages/perennial/contracts/controller/Controller.sol +++ b/packages/perennial/contracts/controller/Controller.sol @@ -299,7 +299,7 @@ contract Controller is IController, UInitializable { * @param product Contract address to check * @return Whether a contract is a product */ - function isProduct(IProduct product) external view returns (bool) { + function isProduct(IProduct product) public view returns (bool) { return coordinatorFor[product] != 0; } @@ -352,6 +352,7 @@ contract Controller is IController, UInitializable { * @return Owner of the product */ function owner(IProduct product) external view returns (address) { + if (!isProduct(product)) revert ControllerNotProductError(); return owner(coordinatorFor[product]); } @@ -382,6 +383,7 @@ contract Controller is IController, UInitializable { * @return Treasury of the product */ function treasury(IProduct product) external view returns (address) { + if (!isProduct(product)) revert ControllerNotProductError(); return treasury(coordinatorFor[product]); } diff --git a/packages/perennial/contracts/interfaces/IController.sol b/packages/perennial/contracts/interfaces/IController.sol index eb97adc9..7b97add1 100644 --- a/packages/perennial/contracts/interfaces/IController.sol +++ b/packages/perennial/contracts/interfaces/IController.sol @@ -40,6 +40,7 @@ interface IController { event CoordinatorCreated(uint256 indexed coordinatorId, address owner); event ProductCreated(IProduct indexed product, IProduct.ProductInfo productInfo); + error ControllerNotProductError(); error ControllerNoZeroCoordinatorError(); error ControllerNotPauserError(); error ControllerNotOwnerError(uint256 controllerId); diff --git a/packages/perennial/test/unit/controller/Controller.test.ts b/packages/perennial/test/unit/controller/Controller.test.ts index 1d1e3ecc..26832c93 100644 --- a/packages/perennial/test/unit/controller/Controller.test.ts +++ b/packages/perennial/test/unit/controller/Controller.test.ts @@ -654,4 +654,24 @@ describe('Controller', () => { .withArgs(0) }) }) + + context('invalid product', () => { + describe('#treasury(IProduct product)', () => { + it('reverts', async () => { + await expect(controller['treasury(address)'](constants.AddressZero)).to.be.revertedWithCustomError( + controller, + 'ControllerNotProductError', + ) + }) + }) + + describe('#owner(IProduct product)', () => { + it('reverts', async () => { + await expect(controller['owner(address)'](constants.AddressZero)).to.be.revertedWithCustomError( + controller, + 'ControllerNotProductError', + ) + }) + }) + }) }) From f75be910d524c761ae4603bd00c427a3ab0f3152 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 9 May 2023 14:38:24 -0400 Subject: [PATCH 14/25] Support type(uint256).max for withdrawAndUnwrap (#176) --- .../contracts/multiinvoker/MultiInvoker.sol | 10 ++++-- .../multiinvoker/multiInvoker.test.ts | 35 +++++++++++++++++++ .../unit/multiinvoker/MultiInvoker.test.ts | 25 +++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol index 5fa5c0f0..218eb28c 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol @@ -276,6 +276,12 @@ contract MultiInvoker is IMultiInvoker, UInitializable { * @param amount Amount of DSU to withdraw from the collateral account */ function _withdrawAndUnwrap(address receiver, IProduct product, UFixed18 amount) internal { + // If amount is uint256 max, withdraw the entire balance + if (amount.eq(UFixed18Lib.MAX)) { + product.settleAccount(msg.sender); + amount = collateral.collateral(msg.sender, product); + } + // Withdraw the amount from the collateral account collateral.withdrawFrom(msg.sender, address(this), product, amount); @@ -371,10 +377,10 @@ contract MultiInvoker is IMultiInvoker, UInitializable { } /** - * @notice Helper function to include an interface fee + * @notice Helper function to include an interface fee * @param receiver The interface receiving the fee * @param amount The amount of DSU to credit the interface - * @param wrapped Bool to specify is USDC is wrapped to DSU + * @param wrapped Bool to specify is USDC is wrapped to DSU */ function _chargeFee(address receiver, UFixed18 amount, bool wrapped) internal { if (wrapped) { diff --git a/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts b/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts index a99617f6..2bdd006d 100644 --- a/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts +++ b/packages/perennial/test/integration/multiinvoker/multiInvoker.test.ts @@ -386,6 +386,41 @@ describe('MultiInvoker', () => { .withArgs(multiInvoker.address, user.address, 10000e6) }) + it('performs WITHDRAW_AND_UNWRAP with max uint256', async () => { + const { user, multiInvoker, batcher, usdc, collateral, reserve, dsu } = instanceVars + + // Load the Reserve with some USDC + await usdc.connect(user).approve(batcher.address, constants.MaxUint256) + await batcher.connect(user).wrap(amount, user.address) + await batcher.rebalance() + + // Deposit the collateral to withdraw + await multiInvoker.connect(user).invoke([actions.DEPOSIT]) + + // Ensure this works without a DSU aproval + await dsu.connect(user).approve(multiInvoker.address, 0) + + const maxActions = buildInvokerActions({ + userAddress: user.address, + productAddress: product.address, + position, + amount: constants.MaxUint256, + programs, + vaultAddress: vault.address, + vaultAmount, + feeAmount: feeAmount, + }) + await expect(multiInvoker.connect(user).invoke([maxActions.WITHDRAW_AND_UNWRAP])) + .to.emit(collateral, 'Withdrawal') + .withArgs(user.address, product.address, amount) + .to.emit(reserve, 'Redeem') + .withArgs(multiInvoker.address, amount, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(reserve.address, multiInvoker.address, 10000e6) + .to.emit(usdc, 'Transfer') + .withArgs(multiInvoker.address, user.address, 10000e6) + }) + it('Skips the reserve if batcher has enough USDC deposits', async () => { const { user, multiInvoker, batcher, usdc, usdcHolder } = instanceVars diff --git a/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts b/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts index d9b339bf..a9c7a58b 100644 --- a/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts +++ b/packages/perennial/test/unit/multiinvoker/MultiInvoker.test.ts @@ -263,6 +263,31 @@ describe('MultiInvoker', () => { expect(batcher.unwrap).to.have.been.calledWith(amount, user.address) }) + it('handles max uint256 amounts in WITHDRAW_AND_UNWRAP action', async () => { + const maxActions = buildInvokerActions({ + userAddress: user.address, + productAddress: product.address, + position, + amount: ethers.constants.MaxUint256, + programs, + vaultAddress: vault.address, + vaultAmount, + feeAmount: feeAmount, + }) + collateral['collateral(address,address)'].whenCalledWith(user.address, product.address).returns(amount) + + await expect(multiInvoker.connect(user).invoke([maxActions.WITHDRAW_AND_UNWRAP])).to.not.be.reverted + + expect(collateral.withdrawFrom).to.have.been.calledWith( + user.address, + multiInvoker.address, + product.address, + amount, + ) + + expect(batcher.unwrap).to.have.been.calledWith(amount, user.address) + }) + it('withdraws then unwraps DSU to USDC using RESERVE on WITHDRAW_AND_UNWRAP action if amount is greater than batcher balance', async () => { usdc.balanceOf.whenCalledWith(batcher.address).returns(0) From 91631f280b59be0d4d7cccf270a1e07ab2b71003 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 9 May 2023 18:48:41 -0400 Subject: [PATCH 15/25] Check if valid program in owner and treasury (#181) --- .../contracts/incentivizer/Incentivizer.sol | 4 ++-- .../unit/incentivizer/Incentivizer.test.ts | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/perennial/contracts/incentivizer/Incentivizer.sol b/packages/perennial/contracts/incentivizer/Incentivizer.sol index 4e642416..90c547c6 100644 --- a/packages/perennial/contracts/incentivizer/Incentivizer.sol +++ b/packages/perennial/contracts/incentivizer/Incentivizer.sol @@ -298,7 +298,7 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe * @param programId Program to return for * @return The owner of `programId` */ - function owner(IProduct product, uint256 programId) public view returns (address) { + function owner(IProduct product, uint256 programId) isProgram(product, programId) public view returns (address) { return controller().owner(_products[product].programInfos[programId].coordinatorId); } @@ -308,7 +308,7 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe * @param programId Program to return for * @return The treasury of `programId` */ - function treasury(IProduct product, uint256 programId) public view returns (address) { + function treasury(IProduct product, uint256 programId) isProgram(product, programId) public view returns (address) { return controller().treasury(_products[product].programInfos[programId].coordinatorId); } diff --git a/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts b/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts index f0897c65..afec2d07 100644 --- a/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts +++ b/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts @@ -2464,4 +2464,24 @@ describe('Incentivizer', () => { ) }) }) + + context('invalid program', () => { + describe('#owner', () => { + it('reverts', async () => { + await expect(incentivizer.owner(product.address, 0)).to.be.revertedWithCustomError( + incentivizer, + 'IncentivizerInvalidProgramError', + ) + }) + }) + + describe('#treasury', () => { + it('reverts', async () => { + await expect(incentivizer.treasury(product.address, 0)).to.be.revertedWithCustomError( + incentivizer, + 'IncentivizerInvalidProgramError', + ) + }) + }) + }) }) From 28a931223db81ad75bba103b78d232add91dc86f Mon Sep 17 00:00:00 2001 From: Arjun Rao <2940142+arjun-io@users.noreply.github.com> Date: Wed, 10 May 2023 10:44:03 -0400 Subject: [PATCH 16/25] fix CI --- packages/perennial-vaults/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/perennial-vaults/package.json b/packages/perennial-vaults/package.json index 067e9419..b0e549ac 100644 --- a/packages/perennial-vaults/package.json +++ b/packages/perennial-vaults/package.json @@ -20,7 +20,7 @@ "test:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat test test/integration/**/*", "test:verification:arbitrum": "FORK_ENABLED=true FORK_NETWORK=arbitrum FORK_BLOCK_NUMBER=80132631 FORK_USE_REAL_DEPLOYS=true hardhat test test/verification/arbitrum/**/*", "coverage": "hardhat coverage --testfiles 'test/unit/**/*'", - "coverage:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat coverage --testfiles 'test/integration/*'", + "coverage:integration": "FORK_ENABLED=true FORK_BLOCK_NUMBER=16581533 hardhat coverage --testfiles 'test/integration/**/*'", "lint": "eslint --fix --ext '.ts,.js' ./ && solhint 'contracts/**/*.sol' --fix", "format": "prettier -w .", "clean": "rm -rf cache artifacts types/generated dist deployments/localhost", From ea7b7b82f1b2e4e5e9493e72923dae8846243cda Mon Sep 17 00:00:00 2001 From: 0xfennel <117121807+0xfennel@users.noreply.github.com> Date: Thu, 11 May 2023 14:21:39 -0700 Subject: [PATCH 17/25] Add more validations in BalancedVault constructor (#180) * Add more validations in BalancedVault constructor * Fix CI * Change error name * Fix typo, validate product payoffs * Add check that previous impl's markets are prefix of current * Natspec --- .../contracts/balanced/BalancedVault.sol | 18 +- .../balanced/BalancedVaultDefinition.sol | 45 ++- .../interfaces/IBalancedVaultDefinition.sol | 9 + .../BalancedVault/balancedVault.test.ts | 128 +++++++- .../BalancedVault/balancedVaultMulti.test.ts | 289 +++++++++++++++++- .../test/integration/helpers/setupHelpers.ts | 4 +- .../multiAssetUpgrades.test.ts | 8 +- 7 files changed, 469 insertions(+), 32 deletions(-) diff --git a/packages/perennial-vaults/contracts/balanced/BalancedVault.sol b/packages/perennial-vaults/contracts/balanced/BalancedVault.sol index 0b4492e3..3badb112 100644 --- a/packages/perennial-vaults/contracts/balanced/BalancedVault.sol +++ b/packages/perennial-vaults/contracts/balanced/BalancedVault.sol @@ -11,7 +11,8 @@ import "./BalancedVaultDefinition.sol"; * @notice ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial. * @dev Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to * maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap - * the maximum amount of assets in the vault. + * the maximum amount of assets in the vault. The long and short markets are expected to have the same oracle and + * opposing payoff functions. * * The vault has a "delayed mint" mechanism for shares on deposit. After depositing to the vault, a user must wait * until the next settlement of the underlying products in order for shares to be reflected in the getters. @@ -86,14 +87,23 @@ contract BalancedVault is IBalancedVault, BalancedVaultDefinition, UInitializabl /// @dev Mapping of the latest epoch for any queued deposit / redemption per user mapping(address => uint256) private _pendingEpochs; + /** + * @notice Constructor for BalancedVaultDefinition + * @dev previousImplementation_ is an optional feature that gives extra protections against parameter errors during the upgrade process + * @param controller_ The controller contract + * @param targetLeverage_ The target leverage for the vault + * @param maxCollateral_ The maximum amount of collateral that can be held in the vault + * @param marketDefinitions_ The market definitions for the vault + * @param previousImplementation_ The previous implementation of the vault. Set to address(0) if there is none + */ constructor( - Token18 asset_, IController controller_, UFixed18 targetLeverage_, UFixed18 maxCollateral_, - MarketDefinition[] memory marketDefinitions_ + MarketDefinition[] memory marketDefinitions_, + IBalancedVaultDefinition previousImplementation_ ) - BalancedVaultDefinition(asset_, controller_, targetLeverage_, maxCollateral_, marketDefinitions_) + BalancedVaultDefinition(controller_, targetLeverage_, maxCollateral_, marketDefinitions_, previousImplementation_) { } /** diff --git a/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol b/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol index 7c247323..c6e5fab8 100644 --- a/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol +++ b/packages/perennial-vaults/contracts/balanced/BalancedVaultDefinition.sol @@ -8,7 +8,8 @@ import "../interfaces/IBalancedVaultDefinition.sol"; * @notice ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial. * @dev Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to * maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap - * the maximum amount of assets in the vault. + * the maximum amount of assets in the vault. The long and short markets are expected to have the same oracle and + * opposing payoff functions. * * The vault has a "delayed mint" mechanism for shares on deposit. After depositing to the vault, a user must wait * until the next settlement of the underlying products in order for shares to be reflected in the getters. @@ -61,20 +62,32 @@ contract BalancedVaultDefinition is IBalancedVaultDefinition { uint256 private immutable weight0; uint256 private immutable weight1; + /** + * @notice Constructor for BalancedVaultDefinition + * @dev previousImplementation_ is an optional feature that gives extra protections against parameter errors during the upgrade process + * @param controller_ The controller contract + * @param targetLeverage_ The target leverage for the vault + * @param maxCollateral_ The maximum amount of collateral that can be held in the vault + * @param marketDefinitions_ The market definitions for the vault + * @param previousImplementation_ The previous implementation of the vault. Set to address(0) if there is none + */ constructor( - Token18 asset_, IController controller_, UFixed18 targetLeverage_, UFixed18 maxCollateral_, - MarketDefinition[] memory marketDefinitions_ + MarketDefinition[] memory marketDefinitions_, + IBalancedVaultDefinition previousImplementation_ ) { - asset = asset_; + if (targetLeverage_.eq(UFixed18Lib.ZERO)) revert BalancedVaultDefinitionZeroTargetLeverageError(); + controller = controller_; collateral = controller_.collateral(); + asset = collateral.token(); targetLeverage = targetLeverage_; maxCollateral = maxCollateral_; uint256 totalMarkets_ = Math.min(marketDefinitions_.length, MAX_MARKETS); + if (totalMarkets_ == 0) revert BalancedVaultDefinitionNoMarketsError(); uint256 totalWeight_; uint256 minWeight_ = type(uint256).max; @@ -87,13 +100,37 @@ contract BalancedVaultDefinition is IBalancedVaultDefinition { weight1 = (totalMarkets_ > 1) ? marketDefinitions_[1].weight : DEFAULT_WEIGHT; for (uint256 marketId; marketId < totalMarkets_; marketId++) { + if (!controller.isProduct(marketDefinitions_[marketId].long)) revert BalancedVaultInvalidProductError(marketDefinitions_[marketId].long); + if (!controller.isProduct(marketDefinitions_[marketId].short)) revert BalancedVaultInvalidProductError(marketDefinitions_[marketId].short); + if (marketDefinitions_[marketId].long == marketDefinitions_[marketId].short) revert BalancedVaultDefinitionLongAndShortAreSameProductError(); + if (marketDefinitions_[marketId].long.oracle() != marketDefinitions_[marketId].short.oracle()) revert BalancedVaultDefinitionOracleMismatchError(); + + PayoffDefinition memory longPayoff = marketDefinitions_[marketId].long.payoffDefinition(); + PayoffDefinition memory shortPayoff = marketDefinitions_[marketId].short.payoffDefinition(); + if (longPayoff.payoffDirection != PayoffDefinitionLib.PayoffDirection.LONG) revert BalancedVaultDefinitionWrongPayoffDirectionError(marketDefinitions_[marketId].long); + if (shortPayoff.payoffDirection != PayoffDefinitionLib.PayoffDirection.SHORT) revert BalancedVaultDefinitionWrongPayoffDirectionError(marketDefinitions_[marketId].short); + if (longPayoff.data != shortPayoff.data) revert BalancedVaultDefinitionMismatchedPayoffDataError(); + totalWeight_ += marketDefinitions_[marketId].weight; if (minWeight_ > marketDefinitions_[marketId].weight) minWeight_ = marketDefinitions_[marketId].weight; } + if (totalWeight_ == 0) revert BalancedVaultDefinitionAllZeroWeightError(); + totalMarkets = totalMarkets_; totalWeight = totalWeight_; minWeight = minWeight_; + + if (address(previousImplementation_) != address(0)) { + // Check that the previous implementation's markets match up to this one. + uint256 previousTotalMarkets_ = previousImplementation_.totalMarkets(); + if (previousTotalMarkets_ > totalMarkets_) revert BalancedVaultDefinitionMarketsMismatchedWithPreviousImplementationError(); + for (uint256 marketId; marketId < previousTotalMarkets_; marketId++) { + MarketDefinition memory previousMarket_ = previousImplementation_.markets(marketId); + if (previousMarket_.long != marketDefinitions_[marketId].long) revert BalancedVaultDefinitionMarketsMismatchedWithPreviousImplementationError(); + if (previousMarket_.short != marketDefinitions_[marketId].short) revert BalancedVaultDefinitionMarketsMismatchedWithPreviousImplementationError(); + } + } } /** diff --git a/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol b/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol index ae58b12f..0140ec67 100644 --- a/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol +++ b/packages/perennial-vaults/contracts/interfaces/IBalancedVaultDefinition.sol @@ -12,6 +12,15 @@ interface IBalancedVaultDefinition { } error BalancedVaultDefinitionInvalidMarketIdError(); + error BalancedVaultDefinitionZeroTargetLeverageError(); + error BalancedVaultDefinitionNoMarketsError(); + error BalancedVaultDefinitionLongAndShortAreSameProductError(); + error BalancedVaultInvalidProductError(IProduct product); + error BalancedVaultDefinitionOracleMismatchError(); + error BalancedVaultDefinitionWrongPayoffDirectionError(IProduct product); + error BalancedVaultDefinitionMismatchedPayoffDataError(); + error BalancedVaultDefinitionAllZeroWeightError(); + error BalancedVaultDefinitionMarketsMismatchedWithPreviousImplementationError(); function asset() external view returns (Token18); function totalMarkets() external view returns (uint256); diff --git a/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts index 6fe951b5..711b6613 100644 --- a/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts @@ -95,13 +95,19 @@ describe('BalancedVault', () => { leverage = utils.parseEther('4.0') maxCollateral = utils.parseEther('500000') - vault = await new BalancedVault__factory(owner).deploy(dsu.address, controller.address, leverage, maxCollateral, [ - { - long: long.address, - short: short.address, - weight: 1, - }, - ]) + vault = await new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ) await vault.initialize('Perennial Vault Alpha') asset = IERC20Metadata__factory.connect(await vault.asset(), owner) @@ -139,6 +145,114 @@ describe('BalancedVault', () => { oracle.atVersion.whenCalledWith(currentVersion[0]).returns(currentVersion) }) + describe('#constructor', () => { + it('checks that there is at least one market', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionNoMarketsError') + }) + + it('checks that at least one weight is greater than zero', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 0, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionAllZeroWeightError') + + // At least one of the weights can be zero as long as not all of them are. + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 0, + }, + { + long: long.address, + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.not.be.reverted + }) + + it('checks that all products are valid', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: '0x0000000000000000000000000000000000000000', + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultInvalidProductError') + }) + + it('checks that target leverage is positive', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + 0, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionZeroTargetLeverageError') + }) + + it('checks that the long and short are not identical', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: long.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionLongAndShortAreSameProductError') + }) + }) + describe('#initialize', () => { it('cant re-initialize', async () => { await expect(vault.initialize('Perennial Vault Alpha')).to.revertedWithCustomError( diff --git a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts index 5149b68c..fce1f854 100644 --- a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts @@ -163,18 +163,24 @@ describe('BalancedVault (Multi-Payoff)', () => { leverage = utils.parseEther('4.0') maxCollateral = utils.parseEther('500000') - vault = await new BalancedVault__factory(owner).deploy(dsu.address, controller.address, leverage, maxCollateral, [ - { - long: long.address, - short: short.address, - weight: 4, - }, - { - long: btcLong.address, - short: btcShort.address, - weight: 1, - }, - ]) + vault = await new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 4, + }, + { + long: btcLong.address, + short: btcShort.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ) await vault.initialize('Perennial Vault Alpha') asset = IERC20Metadata__factory.connect(await vault.asset(), owner) @@ -241,6 +247,265 @@ describe('BalancedVault (Multi-Payoff)', () => { btcOracle.atVersion.whenCalledWith(btcCurrentVersion[0]).returns(btcCurrentVersion) }) + describe('#constructor', () => { + it('checks that there is at least one market', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionNoMarketsError') + }) + + it('checks that at least one weight is greater than zero', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 0, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionAllZeroWeightError') + + // At least one of the weights can be zero as long as not all of them are. + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 0, + }, + { + long: long.address, + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.not.be.reverted + }) + + it('checks that all products are valid', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: '0x0000000000000000000000000000000000000000', + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultInvalidProductError') + }) + + it('checks that target leverage is positive', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + 0, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionZeroTargetLeverageError') + }) + + it('checks that the long and short are not identical', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: long.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionLongAndShortAreSameProductError') + }) + + it('checks that the long and short oracles match', async () => { + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: btcShort.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionOracleMismatchError') + }) + + it('checks that the products have the right direction payoff', async () => { + const incorrectBtcLong = await deployProductOnMainnetFork({ + owner: owner, + name: 'Bitcoin', + symbol: 'BTC', + baseCurrency: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + quoteCurrency: '0x0000000000000000000000000000000000000348', + oracle: btcOracle.address, + short: true, + }) + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: incorrectBtcLong.address, + short: btcShort.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionWrongPayoffDirectionError') + + const incorrectBtcShort = await deployProductOnMainnetFork({ + owner: owner, + name: 'Bitcoin', + symbol: 'BTC', + baseCurrency: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + quoteCurrency: '0x0000000000000000000000000000000000000348', + oracle: btcOracle.address, + short: false, + }) + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: btcLong.address, + short: incorrectBtcShort.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionWrongPayoffDirectionError') + }) + + it('checks that the products have the same payoff data', async () => { + const btcLongWithPayoffData = await deployProductOnMainnetFork({ + owner: owner, + name: 'Bitcoin', + symbol: 'BTC', + baseCurrency: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + quoteCurrency: '0x0000000000000000000000000000000000000348', + oracle: btcOracle.address, + short: false, + payoffOracle: btcOracle.address, + }) + + const btcShortWithPayoffData = await deployProductOnMainnetFork({ + owner: owner, + name: 'Bitcoin', + symbol: 'BTC', + baseCurrency: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + quoteCurrency: '0x0000000000000000000000000000000000000348', + oracle: btcOracle.address, + short: true, + payoffOracle: controller.address, + }) + + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: btcLongWithPayoffData.address, + short: btcShortWithPayoffData.address, + weight: 1, + }, + ], + ethers.constants.AddressZero, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionMismatchedPayoffDataError') + }) + + it('checks that there are at least the markets of the previous implementation is a prefix of that of the new implementation ', async () => { + // New implementation has fewer products than the previous implementation. + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: long.address, + short: short.address, + weight: 4, + }, + ], + vault.address, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionMarketsMismatchedWithPreviousImplementationError') + + // Markets are switched around in the new implementation. + await expect( + new BalancedVault__factory(owner).deploy( + controller.address, + leverage, + maxCollateral, + [ + { + long: btcLong.address, + short: btcShort.address, + weight: 1, + }, + { + long: long.address, + short: short.address, + weight: 4, + }, + ], + vault.address, + ), + ).to.revertedWithCustomError(vault, 'BalancedVaultDefinitionMarketsMismatchedWithPreviousImplementationError') + }) + }) + describe('#initialize', () => { it('cant re-initialize', async () => { await expect(vault.initialize('Perennial Vault Alpha')).to.revertedWithCustomError( diff --git a/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts b/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts index 8038a87c..d1f0f297 100644 --- a/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts +++ b/packages/perennial-vaults/test/integration/helpers/setupHelpers.ts @@ -10,6 +10,7 @@ export interface DeployProductParams extends Partial { ]) const newImpl = await new BalancedVault__factory(signer).deploy( - await vault.asset(), await vault.controller(), await vault.targetLeverage(), await vault.maxCollateral(), [{ long, short, weight: utils.parseEther('1') }], + ethers.constants.AddressZero, ) await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImpl.address) @@ -74,11 +74,11 @@ describe('Vault - Perennial Vaults - Multi-Asset Upgrade', () => { const [long, short] = await Promise.all([prevVault.long(), prevVault.short()]) const newImpl = await new BalancedVault__factory(signer).deploy( - await vault.asset(), await vault.controller(), await vault.targetLeverage(), await vault.maxCollateral(), [{ long, short, weight: utils.parseEther('1') }], + ethers.constants.AddressZero, ) await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImpl.address) }) @@ -103,7 +103,6 @@ describe('Vault - Perennial Vaults - Multi-Asset Upgrade', () => { ]) const newImplMulti = await new BalancedVault__factory(signer).deploy( - await vault.asset(), await vault.controller(), await vault.targetLeverage(), await vault.maxCollateral(), @@ -111,6 +110,7 @@ describe('Vault - Perennial Vaults - Multi-Asset Upgrade', () => { { long: market0.long, short: market0.short, weight: utils.parseEther('1') }, { long: arbLong, short: arbShort, weight: utils.parseEther('0.1') }, ], + ethers.constants.AddressZero, ) await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImplMulti.address) await vault.initialize('PerennialVaultAlpha') @@ -135,7 +135,6 @@ describe('Vault - Perennial Vaults - Multi-Asset Upgrade', () => { const arbShort = deployments['Product_ShortArbitrum'].address const market0 = await vault.markets(0) const newImplMulti = await new BalancedVault__factory(signer).deploy( - await vault.asset(), await vault.controller(), await vault.targetLeverage(), await vault.maxCollateral(), @@ -143,6 +142,7 @@ describe('Vault - Perennial Vaults - Multi-Asset Upgrade', () => { { long: market0.long, short: market0.short, weight: utils.parseEther('0.5') }, { long: arbLong, short: arbShort, weight: utils.parseEther('0.5') }, ], + ethers.constants.AddressZero, ) await proxyAdmin.connect(adminOwner).upgrade(vault.address, newImplMulti.address) await vault.initialize('PerennialVaultAlpha') From b5f0a5f597a34d8376bf1e8d5b02c8c85e8e31cd Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Fri, 12 May 2023 11:18:39 -0400 Subject: [PATCH 18/25] Reavert if round timestamp is 0 (#182) --- .../contracts/ChainlinkFeedOracle.sol | 4 ++-- .../perennial-oracle/contracts/ChainlinkOracle.sol | 4 ++-- .../ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts | 12 ++++++++++++ .../unit/ChainlinkOracle/ChainlinkOracle.test.ts | 6 ++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol index 677848fd..4eb7b989 100644 --- a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol @@ -65,8 +65,8 @@ contract ChainlinkFeedOracle is IOracleProvider { // Fetch latest round ChainlinkRound memory round = aggregator.getLatestRound(); - // Revert if the aggregator round id is 0 which is an invalid round. - if (round.aggregatorRoundId() == 0) revert InvalidOracleRound(); + // Revert if the aggregator round id or timestamp is 0 which is an invalid round. + if (round.aggregatorRoundId() == 0 || round.timestamp == 0) revert InvalidOracleRound(); // Update phase annotation when new phase detected // `_lastSyncedRoundId` is the last round we have seen diff --git a/packages/perennial-oracle/contracts/ChainlinkOracle.sol b/packages/perennial-oracle/contracts/ChainlinkOracle.sol index 6c98194b..8d6d36b6 100644 --- a/packages/perennial-oracle/contracts/ChainlinkOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkOracle.sol @@ -60,8 +60,8 @@ contract ChainlinkOracle is IOracleProvider { // Fetch latest round ChainlinkRound memory round = registry.getLatestRound(base, quote); - // Revert if the round id is 0 - if (uint64(round.roundId) == 0) revert InvalidOracleRound(); + // Revert if the round id or timestamp is 0 + if (uint64(round.roundId) == 0 || round.timestamp == 0) revert InvalidOracleRound(); // Update phase annotation when new phase detected while (round.phaseId() > _latestPhaseId()) { diff --git a/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts b/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts index 702820b2..0265e41a 100644 --- a/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts +++ b/packages/perennial-oracle/test/unit/ChainlinkFeedOracle/ChainlinkFeedOracle.test.ts @@ -361,6 +361,18 @@ describe('ChainlinkFeedOracle', () => { .returns([roundId, ethers.BigNumber.from(133300000000), TIMESTAMP_START, TIMESTAMP_START + HOUR, roundId]) await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'InvalidOracleRound') + + aggregatorProxy.latestRoundData + .whenCalledWith() + .returns([ + buildChainlinkRoundId(1, 1), + ethers.BigNumber.from(133300000000), + 0, + 0, + buildChainlinkRoundId(1, 1), + ]) + + await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'InvalidOracleRound') }) }) }) diff --git a/packages/perennial-oracle/test/unit/ChainlinkOracle/ChainlinkOracle.test.ts b/packages/perennial-oracle/test/unit/ChainlinkOracle/ChainlinkOracle.test.ts index 938f9e41..d6f6cf5f 100644 --- a/packages/perennial-oracle/test/unit/ChainlinkOracle/ChainlinkOracle.test.ts +++ b/packages/perennial-oracle/test/unit/ChainlinkOracle/ChainlinkOracle.test.ts @@ -219,6 +219,12 @@ describe('ChainlinkOracle', () => { .returns(roundId, ethers.BigNumber.from(133300000000), TIMESTAMP_START, TIMESTAMP_START + HOUR, roundId) await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'InvalidOracleRound') + + await registry.mock.latestRoundData + .withArgs(eth.address, usd.address) + .returns(buildChainlinkRoundId(1, 1), ethers.BigNumber.from(133300000000), 0, 0, buildChainlinkRoundId(1, 1)) + + await expect(oracle.connect(user).sync()).to.be.revertedWithCustomError(oracle, 'InvalidOracleRound') }) }) }) From a79a24a3c88f18449345b3cf7fa2fccde6da4680 Mon Sep 17 00:00:00 2001 From: 0xfennel <117121807+0xfennel@users.noreply.github.com> Date: Fri, 12 May 2023 15:21:18 -0700 Subject: [PATCH 19/25] [Nit] Delete unused variables (#184) --- .../test/integration/BalancedVault/balancedVault.test.ts | 5 ----- .../integration/BalancedVault/balancedVaultMulti.test.ts | 6 ------ 2 files changed, 11 deletions(-) diff --git a/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts index 711b6613..60e8e7d7 100644 --- a/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVault.test.ts @@ -30,7 +30,6 @@ describe('BalancedVault', () => { let oracle: FakeContract let collateral: ICollateral let controller: IController - let controllerOwner: SignerWithAddress let owner: SignerWithAddress let user: SignerWithAddress let user2: SignerWithAddress @@ -85,10 +84,6 @@ describe('BalancedVault', () => { const dsu = IERC20Metadata__factory.connect('0x605D26FBd5be761089281d5cec2Ce86eeA667109', owner) controller = IController__factory.connect('0x9df509186b6d3b7D033359f94c8b1BB5544d51b3', owner) - controllerOwner = await impersonate.impersonateWithBalance( - await controller.callStatic['owner()'](), - utils.parseEther('10'), - ) long = IProduct__factory.connect('0xdB60626FF6cDC9dB07d3625A93d21dDf0f8A688C', owner) short = IProduct__factory.connect('0xfeD3E166330341e0305594B8c6e6598F9f4Cbe9B', owner) collateral = ICollateral__factory.connect('0x2d264ebdb6632a06a1726193d4d37fef1e5dbdcd', owner) diff --git a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts index fce1f854..2ec9ec61 100644 --- a/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts +++ b/packages/perennial-vaults/test/integration/BalancedVault/balancedVaultMulti.test.ts @@ -20,7 +20,6 @@ import { ChainlinkOracle__factory, } from '../../../types/generated' import { BigNumber, constants, utils } from 'ethers' -import { product } from '@equilibria/perennial/types/generated/contracts' const { config, ethers } = HRE use(smock.matchers) @@ -33,7 +32,6 @@ describe('BalancedVault (Multi-Payoff)', () => { let oracle: FakeContract let collateral: ICollateral let controller: IController - let controllerOwner: SignerWithAddress let owner: SignerWithAddress let user: SignerWithAddress let user2: SignerWithAddress @@ -130,10 +128,6 @@ describe('BalancedVault (Multi-Payoff)', () => { const dsu = IERC20Metadata__factory.connect('0x605D26FBd5be761089281d5cec2Ce86eeA667109', owner) controller = IController__factory.connect('0x9df509186b6d3b7D033359f94c8b1BB5544d51b3', owner) - controllerOwner = await impersonate.impersonateWithBalance( - await controller.callStatic['owner()'](), - utils.parseEther('10'), - ) long = IProduct__factory.connect('0xdB60626FF6cDC9dB07d3625A93d21dDf0f8A688C', owner) short = IProduct__factory.connect('0xfeD3E166330341e0305594B8c6e6598F9f4Cbe9B', owner) const btcOracleToMock = await new ChainlinkOracle__factory(owner).deploy( From 45de2ad58e0611e4e6def5cb2e321e394158faa1 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Mon, 15 May 2023 11:21:36 -0400 Subject: [PATCH 20/25] [Fix][M1] Reentrancy attack vector through incentive program rewards (#174) * Mark updateClosed as nonReentrant * Move incentivizer refunds to settled flow * Mark updateClosed as notPaused (#175) --- .../contracts/incentivizer/Incentivizer.sol | 11 ++- .../incentivizer/types/ProductManager.sol | 15 +-- .../contracts/incentivizer/types/Program.sol | 8 +- .../contracts/interfaces/IIncentivizer.sol | 1 + .../perennial/contracts/product/Product.sol | 2 +- .../integration/core/incentivizer.test.ts | 18 ++-- .../unit/incentivizer/Incentivizer.test.ts | 97 +++++++++++-------- .../test/unit/product/Product.test.ts | 12 +++ 8 files changed, 103 insertions(+), 61 deletions(-) diff --git a/packages/perennial/contracts/incentivizer/Incentivizer.sol b/packages/perennial/contracts/incentivizer/Incentivizer.sol index 90c547c6..dc0849ce 100644 --- a/packages/perennial/contracts/incentivizer/Incentivizer.sol +++ b/packages/perennial/contracts/incentivizer/Incentivizer.sol @@ -109,8 +109,6 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe */ function _handleSyncResult(IProduct product, ProductManagerLib.SyncResult memory syncResult) private { uint256 programId = syncResult.programId; - if (!syncResult.refundAmount.isZero()) - _products[product].token(programId).push(treasury(product, programId), syncResult.refundAmount); if (syncResult.versionStarted != 0) emit ProgramStarted(product, programId, syncResult.versionStarted); if (syncResult.versionComplete != 0) @@ -312,6 +310,15 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe return controller().treasury(_products[product].programInfos[programId].coordinatorId); } + /** + * @notice Returns the treasury of a specific program + * @param coordinatorId Coordinator to get the treasury for to return for + * @return The treasury of `programId` + */ + function treasury(uint256 coordinatorId) public view returns (address) { + return controller().treasury(coordinatorId); + } + /// @dev Helper to fully settle an account's state modifier settleForAccount(address account, IProduct product) { product.settleAccount(account); diff --git a/packages/perennial/contracts/incentivizer/types/ProductManager.sol b/packages/perennial/contracts/incentivizer/types/ProductManager.sol index e375371f..06d22c85 100644 --- a/packages/perennial/contracts/incentivizer/types/ProductManager.sol +++ b/packages/perennial/contracts/incentivizer/types/ProductManager.sol @@ -40,9 +40,6 @@ library ProductManagerLib { /// @dev If non-zero, the new versionComplete value of the program uint256 versionComplete; - - /// @dev If non-zero, the amount to refund due to completion - UFixed18 refundAmount; } /** @@ -90,13 +87,12 @@ library ProductManagerLib { // If timestamp-completed, grab previous version (last version before completion) uint256 versionComplete; - UFixed18 refundAmount; if (program.versionComplete == 0 && programInfo.isComplete(currentOracleVersion.timestamp)) { - (versionComplete, refundAmount) = _complete(self, product, programId); + versionComplete = _complete(self, product, programId); } // Save result - results[i] = SyncResult(programId, versionStarted, versionComplete, refundAmount); + results[i] = SyncResult(programId, versionStarted, versionComplete); } } @@ -165,7 +161,7 @@ library ProductManagerLib { // If not completed already, complete if (program.versionComplete == 0) { - (result.versionComplete, result.refundAmount) = _complete(self, product, programId); + result.versionComplete = _complete(self, product, programId); } } @@ -195,14 +191,13 @@ library ProductManagerLib { * @param product The Product to operate on * @param programId The Program to complete * @return versionComplete The version that the program complete - * @return refundAmount The refunded token amount */ function _complete( ProductManager storage self, IProduct product, uint256 programId - ) internal returns (uint256 versionComplete, UFixed18 refundAmount) { - (versionComplete, refundAmount) = self.programs[programId].complete(product, self.programInfos[programId]); + ) internal returns (uint256 versionComplete) { + versionComplete = self.programs[programId].complete(product, self.programInfos[programId]); self.activePrograms.remove(programId); } diff --git a/packages/perennial/contracts/incentivizer/types/Program.sol b/packages/perennial/contracts/incentivizer/types/Program.sol index a2bf04f4..a9b4da96 100644 --- a/packages/perennial/contracts/incentivizer/types/Program.sol +++ b/packages/perennial/contracts/incentivizer/types/Program.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.13; +import "../../interfaces/IIncentivizer.sol"; import "../../interfaces/types/ProgramInfo.sol"; /// @dev Program type @@ -52,13 +53,12 @@ library ProgramLib { * @param product The Product to operate on * @param programInfo Static program information * @return versionComplete The version that the program completed on - * @return refundAmount The refund amount from the program */ function complete( Program storage self, IProduct product, ProgramInfo memory programInfo - ) internal returns (uint256 versionComplete, UFixed18 refundAmount) { + ) internal returns (uint256 versionComplete) { uint256 versionStarted = self.versionStarted; versionComplete = Math.max(versionStarted, product.latestVersion()); self.versionComplete = versionComplete; @@ -67,8 +67,10 @@ library ProgramLib { IOracleProvider.OracleVersion memory toOracleVersion = product.atVersion(versionComplete); uint256 inactiveDuration = programInfo.duration - (toOracleVersion.timestamp - fromOracleVersion.timestamp); - refundAmount = programInfo.amount.sum().muldiv(inactiveDuration, programInfo.duration); + UFixed18 refundAmount = programInfo.amount.sum().muldiv(inactiveDuration, programInfo.duration); self.available = self.available.sub(refundAmount); + address treasury = IIncentivizer(address(this)).treasury(programInfo.coordinatorId); + self.settled[treasury] = self.settled[treasury].add(refundAmount); } /** diff --git a/packages/perennial/contracts/interfaces/IIncentivizer.sol b/packages/perennial/contracts/interfaces/IIncentivizer.sol index e142bdd1..66fa96ad 100644 --- a/packages/perennial/contracts/interfaces/IIncentivizer.sol +++ b/packages/perennial/contracts/interfaces/IIncentivizer.sol @@ -40,4 +40,5 @@ interface IIncentivizer { function versionComplete(IProduct product, uint256 programId) external view returns (uint256); function owner(IProduct product, uint256 programId) external view returns (address); function treasury(IProduct product, uint256 programId) external view returns (address); + function treasury(uint256 coordinatorId) external view returns (address); } diff --git a/packages/perennial/contracts/product/Product.sol b/packages/perennial/contracts/product/Product.sol index 34853f48..bf685a2c 100644 --- a/packages/perennial/contracts/product/Product.sol +++ b/packages/perennial/contracts/product/Product.sol @@ -491,7 +491,7 @@ contract Product is IProduct, UInitializable, UParamProvider, UPayoffProvider, U * @dev only callable by product owner. Settles the product before flipping the flag * @param newClosed new closed value */ - function updateClosed(bool newClosed) external onlyProductOwner { + function updateClosed(bool newClosed) external nonReentrant notPaused onlyProductOwner { IOracleProvider.OracleVersion memory oracleVersion = _settle(); _closed.store(newClosed); emit ClosedUpdated(newClosed, oracleVersion.version); diff --git a/packages/perennial/test/integration/core/incentivizer.test.ts b/packages/perennial/test/integration/core/incentivizer.test.ts index 52f192f5..5780df6f 100644 --- a/packages/perennial/test/integration/core/incentivizer.test.ts +++ b/packages/perennial/test/integration/core/incentivizer.test.ts @@ -75,7 +75,8 @@ describe('Incentivizer', () => { expect(await incentivizer.versionComplete(product.address, PROGRAM_ID)).to.equal(0) expect(await incentivizer.owner(product.address, PROGRAM_ID)).to.equal(owner.address) - expect(await incentivizer.treasury(product.address, PROGRAM_ID)).to.equal(treasuryA.address) + expect(await incentivizer['treasury(address,uint256)'](product.address, PROGRAM_ID)).to.equal(treasuryA.address) + expect(await incentivizer['treasury(uint256)'](0)).to.equal(treasuryA.address) }) it('creates a product owned program', async () => { @@ -115,7 +116,8 @@ describe('Incentivizer', () => { expect(await incentivizer.versionComplete(product.address, PROGRAM_ID)).to.equal(0) expect(await incentivizer.owner(product.address, PROGRAM_ID)).to.equal(userB.address) - expect(await incentivizer.treasury(product.address, PROGRAM_ID)).to.equal(treasuryB.address) + expect(await incentivizer['treasury(address,uint256)'](product.address, PROGRAM_ID)).to.equal(treasuryB.address) + expect(await incentivizer['treasury(uint256)'](1)).to.equal(treasuryB.address) }) it('correctly syncs', async () => { @@ -176,8 +178,6 @@ describe('Incentivizer', () => { await chainlink.nextWithTimestampModification(ts => ts.add(2 * YEAR)) await expect(product.settle()) - .to.emit(incentiveToken, 'Transfer') - .withArgs(incentivizer.address, treasuryA.address, '9999662208504801097393') // Refund Amount .to.emit(incentivizer, 'ProgramComplete') .withArgs(product.address, PROGRAM_ID, INITIAL_VERSION + 3) @@ -195,6 +195,10 @@ describe('Incentivizer', () => { expect(await incentivizer.available(product.address, PROGRAM_ID)).to.equal('101808984910837662') expect(await incentivizer.active(product.address)).to.equal(0) + // Refund amount + expect(await incentivizer.unclaimed(product.address, treasuryA.address, PROGRAM_ID)).to.equal( + '9999662208504801097393', + ) }) it('completes early', async () => { @@ -220,8 +224,6 @@ describe('Incentivizer', () => { await product.settle() await expect(incentivizer.complete(product.address, PROGRAM_ID)) - .to.emit(incentiveToken, 'Transfer') - .withArgs(incentivizer.address, treasuryA.address, '9999662208504801097393') // Refund Amount .to.emit(incentivizer, 'ProgramComplete') .withArgs(product.address, PROGRAM_ID, INITIAL_VERSION + 3) @@ -239,6 +241,10 @@ describe('Incentivizer', () => { expect(await incentivizer.available(product.address, PROGRAM_ID)).to.equal('101808984910837662') expect(await incentivizer.active(product.address)).to.equal(0) + // Refund amount + expect(await incentivizer.unclaimed(product.address, treasuryA.address, PROGRAM_ID)).to.equal( + '9999662208504801097393', + ) }) describe('multiple programs on multiple products', async () => { diff --git a/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts b/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts index afec2d07..6cbd41d7 100644 --- a/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts +++ b/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts @@ -143,7 +143,10 @@ describe('Incentivizer', () => { expect(await incentivizer.versionComplete(product.address, EXPECTED_PROGRAM_ID)).to.equal(0) expect(await incentivizer.owner(product.address, EXPECTED_PROGRAM_ID)).to.equal(productOwner.address) - expect(await incentivizer.treasury(product.address, EXPECTED_PROGRAM_ID)).to.equal(productTreasury.address) + expect(await incentivizer['treasury(address,uint256)'](product.address, EXPECTED_PROGRAM_ID)).to.equal( + productTreasury.address, + ) + expect(await incentivizer['treasury(uint256)'](PRODUCT_COORDINATOR_ID)).to.equal(productTreasury.address) }) it('protocol owner can create program', async () => { @@ -180,7 +183,10 @@ describe('Incentivizer', () => { expect(await incentivizer.versionComplete(product.address, EXPECTED_PROGRAM_ID)).to.equal(0) expect(await incentivizer.owner(product.address, EXPECTED_PROGRAM_ID)).to.equal(owner.address) - expect(await incentivizer.treasury(product.address, EXPECTED_PROGRAM_ID)).to.equal(treasury.address) + expect(await incentivizer['treasury(address,uint256)'](product.address, EXPECTED_PROGRAM_ID)).to.equal( + treasury.address, + ) + expect(await incentivizer['treasury(uint256)'](PRODUCT_COORDINATOR_ID)).to.equal(productTreasury.address) }) it('can create program with fee', async () => { @@ -230,7 +236,10 @@ describe('Incentivizer', () => { expect(await incentivizer.versionComplete(product.address, EXPECTED_PROGRAM_ID)).to.equal(0) expect(await incentivizer.owner(product.address, EXPECTED_PROGRAM_ID)).to.equal(owner.address) - expect(await incentivizer.treasury(product.address, EXPECTED_PROGRAM_ID)).to.equal(treasury.address) + expect(await incentivizer['treasury(address,uint256)'](product.address, EXPECTED_PROGRAM_ID)).to.equal( + treasury.address, + ) + expect(await incentivizer['treasury(uint256)'](PRODUCT_COORDINATOR_ID)).to.equal(productTreasury.address) expect(await incentivizer.fees(token.address)).to.equal(utils.parseEther('100')) }) @@ -590,8 +599,6 @@ describe('Incentivizer', () => { await product.mock.latestVersion.withArgs().returns(LATEST_ORACLE_VERSION.version) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('10000')).returns(true) - await product.mock.atVersion.withArgs(CURRENT_ORACLE_VERSION.version).returns(CURRENT_ORACLE_VERSION) await expect(incentivizer.connect(productSigner).sync(CURRENT_ORACLE_VERSION)) @@ -606,6 +613,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(1) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + utils.parseEther('10000'), + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(0) }) @@ -628,8 +638,6 @@ describe('Incentivizer', () => { await product.mock.latestVersion.withArgs().returns(LATEST_ORACLE_VERSION.version) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('10000')).returns(true) - await product.mock.atVersion.withArgs(CURRENT_ORACLE_VERSION.version).returns(CURRENT_ORACLE_VERSION) await expect(incentivizer.connect(productSigner).sync(CURRENT_ORACLE_VERSION)) @@ -644,6 +652,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(1) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + utils.parseEther('10000'), + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(0) }) @@ -666,9 +677,6 @@ describe('Incentivizer', () => { await product.mock.latestVersion.withArgs().returns(LATEST_ORACLE_VERSION.version) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('10000')).returns(true) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('20000')).returns(true) - await product.mock.atVersion.withArgs(CURRENT_ORACLE_VERSION.version).returns(CURRENT_ORACLE_VERSION) await expect(incentivizer.connect(productSigner).sync(CURRENT_ORACLE_VERSION)) @@ -685,8 +693,14 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + utils.parseEther('10000'), + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(CURRENT_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 1)).to.equal( + utils.parseEther('20000'), + ) }) it('doesnt recomplete program', async () => { @@ -707,8 +721,6 @@ describe('Incentivizer', () => { await product.mock.latestVersion.withArgs().returns(PRE_ORACLE_VERSION.version) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('10000')).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await incentivizer.connect(productSigner).sync(STARTED_ORACLE_VERSION) @@ -735,8 +747,6 @@ describe('Incentivizer', () => { .mul(60 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(60 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) await expect(incentivizer.connect(productSigner).sync(CURRENT_ORACLE_VERSION)) @@ -747,8 +757,14 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + utils.parseEther('10000'), + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 1)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) }) }) @@ -825,8 +841,6 @@ describe('Incentivizer', () => { .mul(30 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(30 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) @@ -838,6 +852,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(1) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(0) }) @@ -865,8 +882,6 @@ describe('Incentivizer', () => { .mul(30 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(30 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) @@ -878,6 +893,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(1) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(0) }) @@ -909,9 +927,6 @@ describe('Incentivizer', () => { .mul(60 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(60 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT_2).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) @@ -925,8 +940,14 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 1)).to.equal( + EXPECTED_REFUND_AMOUNT_2, + ) }) it('doesnt recomplete program', async () => { @@ -952,12 +973,13 @@ describe('Incentivizer', () => { .mul(30 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(30 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) await incentivizer.connect(productSigner).sync(CURRENT_ORACLE_VERSION) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) await increase(30 * DAY) @@ -981,8 +1003,6 @@ describe('Incentivizer', () => { .mul(60 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(60 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) await expect(incentivizer.connect(productSigner).sync(CURRENT_ORACLE_VERSION)) @@ -995,6 +1015,9 @@ describe('Incentivizer', () => { expect(await incentivizer.versionComplete(product.address, 0)).to.equal(23) expect(await incentivizer.versionStarted(product.address, 1)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 1)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 1)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) }) }) @@ -1369,8 +1392,6 @@ describe('Incentivizer', () => { await product.mock['latestVersion()'].withArgs().returns(COMPLETE_ORACLE_VERSION.version) await product.mock.atVersion.withArgs(START_ORACLE_VERSION.version).returns(START_ORACLE_VERSION) await product.mock.atVersion.withArgs(COMPLETE_ORACLE_VERSION.version).returns(COMPLETE_ORACLE_VERSION) - await token.mock.transfer.withArgs(productTreasury.address, REFUND_AMOUNT_0).returns(true) - await token.mock.transfer.withArgs(productTreasury.address, REFUND_AMOUNT_1).returns(true) const POST_COMPLETE_ORACLE_VERSION = { price: utils.parseEther('1'), timestamp: await currentBlockTimestamp(), @@ -1509,8 +1530,6 @@ describe('Incentivizer', () => { await product.mock['latestVersion()'].withArgs().returns(COMPLETE_ORACLE_VERSION.version) await product.mock.atVersion.withArgs(START_ORACLE_VERSION.version).returns(START_ORACLE_VERSION) await product.mock.atVersion.withArgs(COMPLETE_ORACLE_VERSION.version).returns(COMPLETE_ORACLE_VERSION) - await token.mock.transfer.withArgs(productTreasury.address, REFUND_AMOUNT_0).returns(true) - await token.mock.transfer.withArgs(productTreasury.address, REFUND_AMOUNT_1).returns(true) const POST_COMPLETE_ORACLE_VERSION = { price: utils.parseEther('1'), timestamp: await currentBlockTimestamp(), @@ -1629,8 +1648,6 @@ describe('Incentivizer', () => { await product.mock['latestVersion()'].withArgs().returns(COMPLETE_ORACLE_VERSION.version) await product.mock.atVersion.withArgs(START_ORACLE_VERSION.version).returns(START_ORACLE_VERSION) await product.mock.atVersion.withArgs(COMPLETE_ORACLE_VERSION.version).returns(COMPLETE_ORACLE_VERSION) - await token.mock.transfer.withArgs(productTreasury.address, REFUND_AMOUNT_0).returns(true) - await token.mock.transfer.withArgs(productTreasury.address, REFUND_AMOUNT_1).returns(true) const POST_COMPLETE_ORACLE_VERSION = { price: utils.parseEther('1'), timestamp: await currentBlockTimestamp(), @@ -1836,8 +1853,6 @@ describe('Incentivizer', () => { await product.mock.latestVersion.withArgs().returns(LATEST_ORACLE_VERSION.version) await product.mock.currentVersion.withArgs().returns(CURRENT_ORACLE_VERSION) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('10000')).returns(true) - await product.mock.atVersion.withArgs(CURRENT_ORACLE_VERSION.version).returns(CURRENT_ORACLE_VERSION) await expect(incentivizer.connect(productOwner).complete(product.address, 0)) @@ -1850,6 +1865,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + utils.parseEther('10000'), + ) }) it('completes correctly after start time', async () => { @@ -1871,8 +1889,6 @@ describe('Incentivizer', () => { await product.mock.latestVersion.withArgs().returns(LATEST_ORACLE_VERSION.version) await product.mock.currentVersion.withArgs().returns(CURRENT_ORACLE_VERSION) - await token.mock.transfer.withArgs(productTreasury.address, utils.parseEther('10000')).returns(true) - await product.mock.atVersion.withArgs(CURRENT_ORACLE_VERSION.version).returns(CURRENT_ORACLE_VERSION) await expect(incentivizer.connect(productOwner).complete(product.address, 0)) @@ -1885,6 +1901,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(CURRENT_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + utils.parseEther('10000'), + ) }) }) @@ -1938,8 +1957,6 @@ describe('Incentivizer', () => { .mul(30 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(30 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) @@ -1951,6 +1968,9 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal( + EXPECTED_REFUND_AMOUNT, + ) }) }) @@ -1989,8 +2009,6 @@ describe('Incentivizer', () => { .mul(30 * DAY - (LATEST_ORACLE_VERSION.timestamp - STARTED_ORACLE_VERSION.timestamp)) .div(30 * DAY) - await token.mock.transfer.withArgs(productTreasury.address, EXPECTED_REFUND_AMOUNT).returns(true) - await product.mock.atVersion.withArgs(STARTED_ORACLE_VERSION.version).returns(STARTED_ORACLE_VERSION) await product.mock.atVersion.withArgs(LATEST_ORACLE_VERSION.version).returns(LATEST_ORACLE_VERSION) @@ -2014,6 +2032,7 @@ describe('Incentivizer', () => { expect(await incentivizer.active(product.address)).to.equal(0) expect(await incentivizer.versionStarted(product.address, 0)).to.equal(STARTED_ORACLE_VERSION.version) expect(await incentivizer.versionComplete(product.address, 0)).to.equal(LATEST_ORACLE_VERSION.version) + expect(await incentivizer.unclaimed(product.address, productTreasury.address, 0)).to.equal(EXPECTED_REFUND_AMOUNT) }) it('reverts if not valid program', async () => { diff --git a/packages/perennial/test/unit/product/Product.test.ts b/packages/perennial/test/unit/product/Product.test.ts index 21fcb1cb..61735151 100644 --- a/packages/perennial/test/unit/product/Product.test.ts +++ b/packages/perennial/test/unit/product/Product.test.ts @@ -370,6 +370,18 @@ describe('Product', () => { 'ParamProviderInvalidParamValue', ) }) + + describe('closed state', () => { + it('closes the product', async () => { + await product.updateClosed(true) + expect(await product.closed()).to.be.true + }) + + it('reverts if paused', async () => { + await controller.mock.paused.withArgs().returns(true) + await expect(product.updateClosed(true)).to.be.revertedWithCustomError(product, 'PausedError') + }) + }) }) describe('positive price market', async () => { From b014fe0c3caefb454e94240c514a77b3b3d254f4 Mon Sep 17 00:00:00 2001 From: Arjun Rao <2940142+arjun-io@users.noreply.github.com> Date: Mon, 15 May 2023 12:22:14 -0400 Subject: [PATCH 21/25] fix unit test --- packages/perennial/test/unit/incentivizer/Incentivizer.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts b/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts index 6cbd41d7..37b4b62b 100644 --- a/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts +++ b/packages/perennial/test/unit/incentivizer/Incentivizer.test.ts @@ -2496,7 +2496,7 @@ describe('Incentivizer', () => { describe('#treasury', () => { it('reverts', async () => { - await expect(incentivizer.treasury(product.address, 0)).to.be.revertedWithCustomError( + await expect(incentivizer['treasury(address,uint256)'](product.address, 0)).to.be.revertedWithCustomError( incentivizer, 'IncentivizerInvalidProgramError', ) From 79f7ff625b181ccf283a0c3e09fb47e65e0f25e4 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Mon, 15 May 2023 21:00:46 -0400 Subject: [PATCH 22/25] Remove ReservoirFeedOracle (#187) --- .../deploy/005_deploy_sfbayc.ts | 57 -- .../contracts/ReservoirFeedOracle.sol | 88 --- .../deploy/002_deploy_reservoiroracle_bayc.ts | 36 -- .../ReservoirFeedOracle.test.ts | 185 ------ packages/perennial/hardhat.config.ts | 1 - .../test/integration/helpers/setupHelpers.ts | 3 +- .../reservoirOracleProduct.test.ts | 593 ------------------ 7 files changed, 1 insertion(+), 962 deletions(-) delete mode 100644 packages/perennial-examples/deploy/005_deploy_sfbayc.ts delete mode 100644 packages/perennial-oracle/contracts/ReservoirFeedOracle.sol delete mode 100644 packages/perennial-oracle/deploy/002_deploy_reservoiroracle_bayc.ts delete mode 100644 packages/perennial-oracle/test/unit/ReservoirFeedOracle/ReservoirFeedOracle.test.ts delete mode 100644 packages/perennial/test/integration/reservoirOracle/reservoirOracleProduct.test.ts diff --git a/packages/perennial-examples/deploy/005_deploy_sfbayc.ts b/packages/perennial-examples/deploy/005_deploy_sfbayc.ts deleted file mode 100644 index bcf669d2..00000000 --- a/packages/perennial-examples/deploy/005_deploy_sfbayc.ts +++ /dev/null @@ -1,57 +0,0 @@ -import '@nomiclabs/hardhat-ethers' -import 'hardhat-deploy' -import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' -import { IController, IController__factory, IProduct } from '../types/generated' -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { createPayoffDefinition, reuseOrDeployProduct } from '../util' - -const EXAMPLE_COORDINATOR_ID = 1 - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const coordinatorID = process.env.COORDINATOR_ID ? parseInt(process.env.COORDINATOR_ID) : EXAMPLE_COORDINATOR_ID - const { deployments, getNamedAccounts, ethers } = hre - const { get, getOrNull } = deployments - const { deployer } = await getNamedAccounts() - const deployerSigner: SignerWithAddress = await ethers.getSigner(deployer) - - // NETWORK CONSTANTS - const controller: IController = IController__factory.connect((await get('Controller_Proxy')).address, deployerSigner) - console.log('using Controller at ' + controller.address) - - // Check coordinator owner - if (deployerSigner.address !== (await controller['owner(uint256)'](coordinatorID))) { - process.stdout.write('not deploying from coordinator owner address... exiting.') - return - } - - const oracle = await getOrNull('ReservoirFeedOracle_BAYC') - if (oracle == null) { - console.log('ReservoirFeedOracle_BAYC deployment not found... skipping') - return - } - - const productInfo: IProduct.ProductInfoStruct = { - name: 'Short Floor BAYC', - symbol: 'sfBAYC', - payoffDefinition: createPayoffDefinition({ short: true }), - oracle: oracle.address, - maintenance: ethers.utils.parseEther('0.20'), - fundingFee: 0, - makerFee: 0, - takerFee: 0, - positionFee: 0, - makerLimit: ethers.utils.parseEther('2500'), - utilizationCurve: { - minRate: ethers.utils.parseEther('0.04'), - maxRate: ethers.utils.parseEther('16.25'), - targetRate: ethers.utils.parseEther('1.56'), - targetUtilization: ethers.utils.parseEther('0.80'), - }, - } - - await reuseOrDeployProduct(hre, coordinatorID, controller, productInfo) -} - -export default func -func.tags = ['FloorBAYC'] diff --git a/packages/perennial-oracle/contracts/ReservoirFeedOracle.sol b/packages/perennial-oracle/contracts/ReservoirFeedOracle.sol deleted file mode 100644 index f56b2835..00000000 --- a/packages/perennial-oracle/contracts/ReservoirFeedOracle.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; - -import "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; -import "./interfaces/IOracleProvider.sol"; - -/** - * @title ReservoirFeedOracle - * @notice Reservoir implementation of the IOracle interface, using Reservoir's AggregatorV3Interface adaptors - * @dev This is a naive implementation which pushes all validation to the underlying. No staleness checks are possible - This oracle should not be used for regular Chainlink Data Feeds - */ -contract ReservoirFeedOracle is IOracleProvider { - error InvalidOracleVersion(); - - /// @dev Chainlink price feed to read from - AggregatorV3Interface public immutable feed; - - /// @dev Decimal offset used to normalize chainlink price to 18 decimals - int256 private immutable _decimalOffset; - - /// @dev Which underlying round to consider version 0: version = roundId - _versionOffset - uint80 private immutable _versionOffset; - - /** - * @notice Initializes the contract state - * @param feed_ Reservoir price feed - * @param versionOffset_ Version offset from source round ID - */ - constructor(AggregatorV3Interface feed_, uint80 versionOffset_) { - feed = feed_; - _versionOffset = versionOffset_; - _decimalOffset = SafeCast.toInt256(10 ** feed_.decimals()); - } - - /** - * @notice Checks for a new price. Does not perform staleness validation as the underlying oracle does not - support this. - * @return The current oracle version after sync - */ - function sync() external view returns (OracleVersion memory) { - (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.latestRoundData(); - - return _buildOracleVersion(roundId, feedPrice, timestamp); - } - - /** - * @notice Returns the current oracle version - * @return oracleVersion Current oracle version - */ - function currentVersion() public view returns (OracleVersion memory oracleVersion) { - (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.latestRoundData(); - - return _buildOracleVersion(roundId, feedPrice, timestamp); - } - - /** - * @notice Returns the oracle version specified - * @dev Converts the passed in version to a roundID by adding _versionOffset - * @param version The version of which to lookup - * @return oracleVersion Oracle version at version `version` - */ - function atVersion(uint256 version) public view returns (OracleVersion memory oracleVersion) { - // To convert from version to roundId, we add the versionOffset - uint256 feedRoundID = version + _versionOffset; - if (feedRoundID > type(uint80).max) revert InvalidOracleVersion(); - (uint80 roundId, int256 feedPrice, , uint256 timestamp,) = feed.getRoundData(uint80(feedRoundID)); - - return _buildOracleVersion(roundId, feedPrice, timestamp); - } - - /** - * @notice Builds an oracle version object from a Chainlink round object - * @dev Converts the passed in roundID to a version by subtracting _versionOffset - * @param roundId ReservoirRoundId round to build from - * @param feedPrice price returns by the oracle - * @param timestamp round timestamps - * @return Built oracle version - */ - function _buildOracleVersion(uint80 roundId, int256 feedPrice, uint256 timestamp) - private view returns (OracleVersion memory) { - Fixed18 price = Fixed18Lib.ratio(feedPrice, _decimalOffset); - - // To convert from roundId to version, we subtract the versionOffset - return OracleVersion({ version: roundId - _versionOffset, timestamp: timestamp, price: price }); - } -} diff --git a/packages/perennial-oracle/deploy/002_deploy_reservoiroracle_bayc.ts b/packages/perennial-oracle/deploy/002_deploy_reservoiroracle_bayc.ts deleted file mode 100644 index 375e9290..00000000 --- a/packages/perennial-oracle/deploy/002_deploy_reservoiroracle_bayc.ts +++ /dev/null @@ -1,36 +0,0 @@ -import '@nomiclabs/hardhat-ethers' -import 'hardhat-deploy' -import '@nomiclabs/hardhat-ethers' -import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployments, getNamedAccounts } = hre - const { deploy, getOrNull } = deployments - const { deployer } = await getNamedAccounts() - - // NETWORK CONSTANTS - - const reservoirBAYCDataFeedAddress = (await getOrNull('ReservoirDataFeedBAYCUSDC'))?.address - - if (reservoirBAYCDataFeedAddress == null) { - console.log('no deployment found for ReservoirDataFeedBAYCUSDC') - return - } - - console.log('using ReservoirDataFeedBAYCUSDC address: ' + reservoirBAYCDataFeedAddress) - - // ORACLE - - await deploy('ReservoirFeedOracle_BAYC', { - contract: 'ReservoirFeedOracle', - args: [reservoirBAYCDataFeedAddress, 0], - from: deployer, - skipIfAlreadyDeployed: true, - log: true, - autoMine: true, - }) -} - -export default func -func.tags = ['ReservoirOracle_BAYC'] diff --git a/packages/perennial-oracle/test/unit/ReservoirFeedOracle/ReservoirFeedOracle.test.ts b/packages/perennial-oracle/test/unit/ReservoirFeedOracle/ReservoirFeedOracle.test.ts deleted file mode 100644 index db41c544..00000000 --- a/packages/perennial-oracle/test/unit/ReservoirFeedOracle/ReservoirFeedOracle.test.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { smock, FakeContract } from '@defi-wonderland/smock' -import { utils } from 'ethers' -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -import { expect, use } from 'chai' -import HRE from 'hardhat' - -import { - ReservoirFeedOracle, - ReservoirFeedOracle__factory, - AggregatorV3Interface, - AggregatorV3Interface__factory, -} from '../../../types/generated' -import { currentBlockTimestamp } from '../../../../common/testutil/time' - -const { ethers } = HRE - -const HOUR = 60 * 60 -use(smock.matchers) - -describe('ReservoirFeedOracle', () => { - let owner: SignerWithAddress - let user: SignerWithAddress - - let feed: FakeContract - - let oracle: ReservoirFeedOracle - - beforeEach(async () => { - ;[owner, user] = await ethers.getSigners() - feed = await smock.fake(AggregatorV3Interface__factory.abi) - }) - - describe('#constructor', async () => { - it('sets initial params', async () => { - await feed.decimals.returns(8) - - oracle = await new ReservoirFeedOracle__factory(owner).deploy(feed.address, 0) - - expect(await oracle.feed()).to.equal(feed.address) - expect(feed.decimals).to.have.been.called - }) - }) - - describe('#sync', async () => { - let TIMESTAMP_START: number - - beforeEach(async () => { - TIMESTAMP_START = await currentBlockTimestamp() - - await feed.decimals.returns(8) - oracle = await new ReservoirFeedOracle__factory(owner).deploy(feed.address, 0) - }) - - it('syncs first version', async () => { - const roundId = 23 - await feed.latestRoundData.returns([ - roundId, - ethers.BigNumber.from(111100000000), - TIMESTAMP_START - HOUR, - TIMESTAMP_START, - roundId, - ]) - - await feed.getRoundData.returns([ - roundId, - ethers.BigNumber.from(111100000000), - TIMESTAMP_START - HOUR, - TIMESTAMP_START, - roundId, - ]) - - const returnValue = await oracle.callStatic.sync() - oracle.connect(user).sync() - - expect(returnValue.price).to.equal(utils.parseEther('1111')) - expect(returnValue.timestamp).to.equal(TIMESTAMP_START) - expect(returnValue.version).to.equal(23) - - const currentVersion = await oracle.currentVersion() - expect(currentVersion.price).to.equal(utils.parseEther('1111')) - expect(currentVersion.timestamp).to.equal(TIMESTAMP_START) - expect(currentVersion.version).to.equal(23) - - const atVersion = await oracle.atVersion(23) - expect(atVersion.price).to.equal(utils.parseEther('1111')) - expect(atVersion.timestamp).to.equal(TIMESTAMP_START) - expect(atVersion.version).to.equal(23) - }) - - describe('after synced', async () => { - beforeEach(async () => { - const roundId = 23 - - await feed.latestRoundData.returns([ - roundId, - ethers.BigNumber.from(111100000000), - TIMESTAMP_START - HOUR, - TIMESTAMP_START, - roundId, - ]) - - await oracle.connect(user).sync() - }) - - it('syncs new version if available', async () => { - const roundId = 24 - await feed.latestRoundData.returns([ - roundId, - ethers.BigNumber.from(122200000000), - TIMESTAMP_START, - TIMESTAMP_START + HOUR, - roundId, - ]) - - await feed.getRoundData.returns([ - roundId, - ethers.BigNumber.from(122200000000), - TIMESTAMP_START, - TIMESTAMP_START + HOUR, - roundId, - ]) - - const returnValue = await oracle.callStatic.sync() - oracle.connect(user).sync() - - expect(returnValue.price).to.equal(utils.parseEther('1222')) - expect(returnValue.timestamp).to.equal(TIMESTAMP_START + HOUR) - expect(returnValue.version).to.equal(24) - - const currentVersion = await oracle.currentVersion() - expect(currentVersion.price).to.equal(utils.parseEther('1222')) - expect(currentVersion.timestamp).to.equal(TIMESTAMP_START + HOUR) - expect(currentVersion.version).to.equal(24) - - const atVersion = await oracle.atVersion(24) - expect(atVersion.price).to.equal(utils.parseEther('1222')) - expect(atVersion.timestamp).to.equal(TIMESTAMP_START + HOUR) - expect(atVersion.version).to.equal(24) - }) - }) - }) - - describe('#atVersion', async () => { - let TIMESTAMP_START: number - - beforeEach(async () => { - TIMESTAMP_START = await currentBlockTimestamp() - - await feed.decimals.returns(8) - oracle = await new ReservoirFeedOracle__factory(owner).deploy(feed.address, 0) - - const roundId = 23 - - await feed.latestRoundData.returns([ - roundId, - ethers.BigNumber.from(111100000000), - TIMESTAMP_START - HOUR, - TIMESTAMP_START, - roundId, - ]) - - await oracle.connect(user).sync() - }) - - it('reads prior version', async () => { - const roundId = 12 - - await feed.getRoundData - .whenCalledWith(roundId) - .returns([roundId, ethers.BigNumber.from(111100000000), TIMESTAMP_START - HOUR, TIMESTAMP_START, roundId]) - - const atVersion = await oracle.atVersion(12) - expect(atVersion.price).to.equal(utils.parseEther('1111')) - expect(atVersion.timestamp).to.equal(TIMESTAMP_START) - expect(atVersion.version).to.equal(12) - }) - - it('reverts if reading an invalid version', async () => { - await expect(oracle.atVersion(utils.parseEther('10000000000000000'))).to.be.revertedWithCustomError( - oracle, - 'InvalidOracleVersion', - ) - }) - }) -}) diff --git a/packages/perennial/hardhat.config.ts b/packages/perennial/hardhat.config.ts index 4b59118b..ca2c76d0 100644 --- a/packages/perennial/hardhat.config.ts +++ b/packages/perennial/hardhat.config.ts @@ -69,7 +69,6 @@ const config = defaultConfig({ '@openzeppelin/contracts/governance/TimelockController.sol', '@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol', '@equilibria/perennial-oracle/contracts/ChainlinkOracle.sol', - '@equilibria/perennial-oracle/contracts/ReservoirFeedOracle.sol', '@equilibria/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol', '@equilibria/perennial-oracle/contracts/test/PassthroughDataFeed.sol', '@equilibria/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol', diff --git a/packages/perennial/test/integration/helpers/setupHelpers.ts b/packages/perennial/test/integration/helpers/setupHelpers.ts index b7a32e11..a60b6ae4 100644 --- a/packages/perennial/test/integration/helpers/setupHelpers.ts +++ b/packages/perennial/test/integration/helpers/setupHelpers.ts @@ -30,7 +30,6 @@ import { ProxyAdmin, ProxyAdmin__factory, TransparentUpgradeableProxy__factory, - ReservoirFeedOracle, MultiInvoker, MultiInvoker__factory, IEmptySetReserve, @@ -217,7 +216,7 @@ export async function deployProtocol(): Promise { export async function createProduct( instanceVars: InstanceVars, payoffProvider?: TestnetContractPayoffProvider, - oracle?: ChainlinkOracle | ReservoirFeedOracle, + oracle?: ChainlinkOracle, ): Promise { const { owner, controller, treasuryB, chainlinkOracle } = instanceVars if (!payoffProvider) { diff --git a/packages/perennial/test/integration/reservoirOracle/reservoirOracleProduct.test.ts b/packages/perennial/test/integration/reservoirOracle/reservoirOracleProduct.test.ts deleted file mode 100644 index 2e9c601c..00000000 --- a/packages/perennial/test/integration/reservoirOracle/reservoirOracleProduct.test.ts +++ /dev/null @@ -1,593 +0,0 @@ -import { expect } from 'chai' -import 'hardhat' -import { BigNumber, utils } from 'ethers' - -import { InstanceVars, deployProtocol, createProduct, depositTo } from '../helpers/setupHelpers' -import { createPayoffDefinition, expectPositionEq, expectPrePositionEq } from '../../../../common/testutil/types' -import { DataFeedContext } from '../helpers/feedOracleHelper' -import { - ReservoirFeedOracle, - ReservoirFeedOracle__factory, - TestnetContractPayoffProvider, - TestnetContractPayoffProvider__factory, -} from '../../../types/generated' -import { deployments } from 'hardhat' - -const VERSION_OFFSET = BigNumber.from('92233720368547761313') -const INITIAL_VERSION = BigNumber.from(1) -const PRODUCT_INFO = { - name: 'Squeeth', - symbol: 'SQTH', - payoffDefinition: createPayoffDefinition(), - oracle: '', - maintenance: utils.parseEther('0.3'), - fundingFee: utils.parseEther('0.1'), - makerFee: 0, - takerFee: 0, - positionFee: 0, - makerLimit: utils.parseEther('1'), - utilizationCurve: { - minRate: 0, - maxRate: utils.parseEther('5.00'), - targetRate: utils.parseEther('0.80'), - targetUtilization: utils.parseEther('0.80'), - }, -} - -describe('Reservoir Oracle Product', () => { - let instanceVars: InstanceVars - let oracleFeed: DataFeedContext - let reservoirOracle: ReservoirFeedOracle - let baycUSDCPayoffProvider: TestnetContractPayoffProvider - - beforeEach(async () => { - instanceVars = await deployProtocol() - const { owner } = instanceVars - - // Reservoir has not deployed their feed adaptor to mainnet, so for now use Chainlink's DPI feed as a standin - // TODO(arjun): Update this with Reservoir's mainnet deploy - const baycUSDCFeed = (await deployments.get('ChainlinkDPIFeed')).address - oracleFeed = new DataFeedContext(baycUSDCFeed, VERSION_OFFSET) - await oracleFeed.init() - - reservoirOracle = await new ReservoirFeedOracle__factory(owner).deploy(oracleFeed.feed.address, VERSION_OFFSET) - baycUSDCPayoffProvider = await new TestnetContractPayoffProvider__factory(owner).deploy() - PRODUCT_INFO.oracle = reservoirOracle.address - PRODUCT_INFO.payoffDefinition = createPayoffDefinition({ contractAddress: baycUSDCPayoffProvider.address }) - - await oracleFeed.next() - }) - - it('creates a product', async () => { - const { owner, user, controller, collateral, treasuryB, dsu } = instanceVars - - await expect(controller.connect(owner).createCoordinator()) - .to.emit(controller, 'CoordinatorCreated') - .withArgs(1, owner.address) - await expect(controller.updateCoordinatorTreasury(1, treasuryB.address)) - .to.emit(controller, 'CoordinatorTreasuryUpdated') - .withArgs(1, treasuryB.address) - - const productAddress = await controller.callStatic.createProduct(1, PRODUCT_INFO) - await expect(controller.createProduct(1, PRODUCT_INFO)).to.emit(controller, 'ProductCreated') - - await dsu.connect(user).approve(collateral.address, utils.parseEther('1000')) - await collateral.connect(user).depositTo(user.address, productAddress, utils.parseEther('1000')) - - expect(await collateral['collateral(address)'](productAddress)).to.equal(utils.parseEther('1000')) - expect(await collateral.shortfall(productAddress)).to.equal(0) - }) - - it('opens a make position', async () => { - const POSITION = utils.parseEther('0.0001') - const { user } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - - await expect(product.connect(user).openMake(POSITION)) - .to.emit(product, 'MakeOpened') - .withArgs(user.address, INITIAL_VERSION, POSITION) - - // Check user is in the correct state - expect(await product.isClosed(user.address)).to.equal(false) - expectPositionEq(await product.position(user.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: POSITION, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION) - - // Check global state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: POSITION, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // Settle the product with a new oracle version - await oracleFeed.next() - await product.settle() - - // Check global post-settlement state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(1)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(1)), { maker: POSITION, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - - // Settle user and check state - await product.settleAccount(user.address) - expectPositionEq(await product.position(user.address), { maker: POSITION, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION.add(1)) - }) - - it('opens multiple make positions', async () => { - const POSITION = utils.parseEther('0.0001') - const { user } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - - await product.connect(user).openMake(POSITION.div(2)) - - await expect(product.connect(user).openMake(POSITION.div(2))) - .to.emit(product, 'MakeOpened') - .withArgs(user.address, INITIAL_VERSION, POSITION.div(2)) - - // Check user is in the correct state - expect(await product.isClosed(user.address)).to.equal(false) - expectPositionEq(await product.position(user.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: POSITION, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION) - - // Check global state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: POSITION, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // Settle the product with a new oracle version - await oracleFeed.next() - await product.settle() - - // Check global post-settlement state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(1)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(1)), { maker: POSITION, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - - // Settle user and check state - await product.settleAccount(user.address) - expectPositionEq(await product.position(user.address), { maker: POSITION, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION.add(1)) - }) - - it('closes a make position', async () => { - const OPEN_POSITION = utils.parseEther('0.0001') - const CLOSE_POSITION = utils.parseEther('0.0001') - const { user } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - await product.connect(user).openMake(OPEN_POSITION) - - await expect(product.connect(user).closeMake(CLOSE_POSITION)) - .to.emit(product, 'MakeClosed') - .withArgs(user.address, INITIAL_VERSION, CLOSE_POSITION) - - // User state - expect(await product.isClosed(user.address)).to.equal(false) - expect(await product['maintenance(address)'](user.address)).to.equal(0) - expect(await product.maintenanceNext(user.address)).to.equal(0) - expectPositionEq(await product.position(user.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: OPEN_POSITION, taker: 0 }, - closePosition: { maker: CLOSE_POSITION, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION) - - // Global State - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: OPEN_POSITION, taker: 0 }, - closePosition: { maker: CLOSE_POSITION, taker: 0 }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // Settle the product with a new oracle version - await oracleFeed.next() - await product.settle() - - // Check global post-settlement state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(1)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(1)), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - - // Settle user and check state - await product.settleAccount(user.address) - expect(await product.isClosed(user.address)).to.equal(true) - expectPositionEq(await product.position(user.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION.add(1)) - }) - - it('closes multiple make positions', async () => { - const OPEN_POSITION = utils.parseEther('0.0001') - const CLOSE_POSITION = utils.parseEther('0.0001') - const { user } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - await product.connect(user).openMake(OPEN_POSITION) - await product.connect(user).closeMake(CLOSE_POSITION.div(2)) - - await expect(product.connect(user).closeMake(CLOSE_POSITION.div(2))) - .to.emit(product, 'MakeClosed') - .withArgs(user.address, INITIAL_VERSION, CLOSE_POSITION.div(2)) - - // User state - expect(await product.isClosed(user.address)).to.equal(false) - expect(await product['maintenance(address)'](user.address)).to.equal(0) - expect(await product.maintenanceNext(user.address)).to.equal(0) - expectPositionEq(await product.position(user.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: OPEN_POSITION, taker: 0 }, - closePosition: { maker: CLOSE_POSITION, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION) - - // Global State - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: OPEN_POSITION, taker: 0 }, - closePosition: { maker: CLOSE_POSITION, taker: 0 }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // Settle the product with a new oracle version - await oracleFeed.next() - await product.settle() - - // Check global post-settlement state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(1)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(1)), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - - // Settle user and check state - await product.settleAccount(user.address) - expect(await product.isClosed(user.address)).to.equal(true) - expectPositionEq(await product.position(user.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](user.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](user.address)).to.equal(INITIAL_VERSION.add(1)) - }) - - it('opens a take position', async () => { - const MAKE_POSITION = utils.parseEther('0.0001') - const TAKE_POSITION = utils.parseEther('0.00001') - const { user, userB, chainlinkOracle } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - await depositTo(instanceVars, userB, product, utils.parseEther('1000')) - - await product.connect(user).openMake(MAKE_POSITION) - await expect(product.connect(userB).openTake(TAKE_POSITION)) - .to.emit(product, 'TakeOpened') - .withArgs(userB.address, INITIAL_VERSION, TAKE_POSITION) - - // User State - expect(await product.isClosed(userB.address)).to.equal(false) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: 0, taker: TAKE_POSITION }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION) - - // Global State - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: MAKE_POSITION, taker: TAKE_POSITION }, - closePosition: { maker: 0, taker: 0 }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // One round - await oracleFeed.next() - await chainlinkOracle.sync() - - // Another round - await oracleFeed.next() - await product.settle() - - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(2)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(2)), { - maker: MAKE_POSITION, - taker: TAKE_POSITION, - }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - await product.settleAccount(userB.address) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: TAKE_POSITION }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION.add(2)) - }) - - it('opens multiple take positions', async () => { - const MAKE_POSITION = utils.parseEther('0.0001') - const TAKE_POSITION = utils.parseEther('0.00001') - const { user, userB, chainlinkOracle } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - await depositTo(instanceVars, userB, product, utils.parseEther('1000')) - - await product.connect(user).openMake(MAKE_POSITION) - await product.connect(userB).openTake(TAKE_POSITION.div(2)) - - await expect(product.connect(userB).openTake(TAKE_POSITION.div(2))) - .to.emit(product, 'TakeOpened') - .withArgs(userB.address, INITIAL_VERSION, TAKE_POSITION.div(2)) - - // User State - expect(await product.isClosed(userB.address)).to.equal(false) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: 0, taker: TAKE_POSITION }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION) - - // Global State - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: MAKE_POSITION, taker: TAKE_POSITION }, - closePosition: { maker: 0, taker: 0 }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // One round - await oracleFeed.next() - await chainlinkOracle.sync() - - // Another round - await oracleFeed.next() - await product.settle() - - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(2)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(2)), { - maker: MAKE_POSITION, - taker: TAKE_POSITION, - }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - await product.settleAccount(userB.address) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: TAKE_POSITION }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION.add(2)) - }) - - it('closes a take position', async () => { - const OPEN_MAKE_POSITION = utils.parseEther('0.0001') - const OPEN_TAKE_POSITION = utils.parseEther('0.00001') - const CLOSE_TAKE_POSITION = utils.parseEther('0.00001') - const { user, userB } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - await depositTo(instanceVars, userB, product, utils.parseEther('1000')) - - await expect(product.connect(userB).openTake(OPEN_TAKE_POSITION)) - .to.be.revertedWithCustomError(product, 'ProductInsufficientLiquidityError') - .withArgs(0) - await product.connect(user).openMake(OPEN_MAKE_POSITION) - await product.connect(userB).openTake(OPEN_TAKE_POSITION) - - await expect(product.connect(userB).closeTake(CLOSE_TAKE_POSITION)) - .to.emit(product, 'TakeClosed') - .withArgs(userB.address, INITIAL_VERSION, CLOSE_TAKE_POSITION) - - // User State - expect(await product.isClosed(userB.address)).to.equal(false) - expect(await product['maintenance(address)'](userB.address)).to.equal(0) - expect(await product.maintenanceNext(userB.address)).to.equal(0) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: 0, taker: OPEN_TAKE_POSITION }, - closePosition: { maker: 0, taker: CLOSE_TAKE_POSITION }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION) - - // Global State - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: OPEN_MAKE_POSITION, taker: OPEN_TAKE_POSITION }, - closePosition: { maker: 0, taker: CLOSE_TAKE_POSITION }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // Settle the product with a new oracle version - await oracleFeed.next() - await product.settle() - - // Check global post-settlement state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(1)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(1)), { maker: OPEN_MAKE_POSITION, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - - // Settle user and check state - await product.settleAccount(userB.address) - expect(await product.isClosed(userB.address)).to.equal(true) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION.add(1)) - }) - - it('closes multiple take positions', async () => { - const OPEN_MAKE_POSITION = utils.parseEther('0.0001') - const OPEN_TAKE_POSITION = utils.parseEther('0.00001') - const CLOSE_TAKE_POSITION = utils.parseEther('0.00001') - const { user, userB } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - await depositTo(instanceVars, user, product, utils.parseEther('1000')) - await depositTo(instanceVars, userB, product, utils.parseEther('1000')) - - await expect(product.connect(userB).openTake(OPEN_TAKE_POSITION)) - .to.be.revertedWithCustomError(product, 'ProductInsufficientLiquidityError') - .withArgs(0) - await product.connect(user).openMake(OPEN_MAKE_POSITION) - await product.connect(userB).openTake(OPEN_TAKE_POSITION) - await product.connect(userB).closeTake(CLOSE_TAKE_POSITION.div(2)) - - await expect(product.connect(userB).closeTake(CLOSE_TAKE_POSITION.div(2))) - .to.emit(product, 'TakeClosed') - .withArgs(userB.address, INITIAL_VERSION, CLOSE_TAKE_POSITION.div(2)) - - // User State - expect(await product.isClosed(userB.address)).to.equal(false) - expect(await product['maintenance(address)'](userB.address)).to.equal(0) - expect(await product.maintenanceNext(userB.address)).to.equal(0) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: 0, taker: OPEN_TAKE_POSITION }, - closePosition: { maker: 0, taker: CLOSE_TAKE_POSITION }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION) - - // Global State - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: INITIAL_VERSION, - openPosition: { maker: OPEN_MAKE_POSITION, taker: OPEN_TAKE_POSITION }, - closePosition: { maker: 0, taker: CLOSE_TAKE_POSITION }, - }) - expectPositionEq(await product.valueAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - expectPositionEq(await product.shareAtVersion(INITIAL_VERSION), { maker: 0, taker: 0 }) - - // Settle the product with a new oracle version - await oracleFeed.next() - await product.settle() - - // Check global post-settlement state - expect(await product['latestVersion()']()).to.equal(INITIAL_VERSION.add(1)) - expectPositionEq(await product.positionAtVersion(INITIAL_VERSION.add(1)), { maker: OPEN_MAKE_POSITION, taker: 0 }) - expectPrePositionEq(await product['pre()'](), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - - // Settle user and check state - await product.settleAccount(userB.address) - expect(await product.isClosed(userB.address)).to.equal(true) - expectPositionEq(await product.position(userB.address), { maker: 0, taker: 0 }) - expectPrePositionEq(await product['pre(address)'](userB.address), { - oracleVersion: 0, - openPosition: { maker: 0, taker: 0 }, - closePosition: { maker: 0, taker: 0 }, - }) - expect(await product['latestVersion(address)'](userB.address)).to.equal(INITIAL_VERSION.add(1)) - }) - - it('settle no op (gas test)', async () => { - const { user } = instanceVars - - const product = await createProduct(instanceVars, baycUSDCPayoffProvider, reservoirOracle) - - await product.settle() - await product.settle() - await product.settleAccount(user.address) - await product.settleAccount(user.address) - }) -}) From 395a3308a9848e38a00128a630ca921eba539ef0 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 16 May 2023 10:41:42 -0400 Subject: [PATCH 23/25] Don't return struct when deducting program fee (#179) * Don't return struct when deducting program fee * move program total --- .../contracts/incentivizer/Incentivizer.sol | 13 +++++++------ .../contracts/interfaces/types/ProgramInfo.sol | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/perennial/contracts/incentivizer/Incentivizer.sol b/packages/perennial/contracts/incentivizer/Incentivizer.sol index dc0849ce..89b5f41b 100644 --- a/packages/perennial/contracts/incentivizer/Incentivizer.sol +++ b/packages/perennial/contracts/incentivizer/Incentivizer.sol @@ -37,7 +37,7 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe * @param programInfo Parameters for the new program * @return programId New program's ID */ - function create(IProduct product, ProgramInfo calldata programInfo) + function create(IProduct product, ProgramInfo memory programInfo) external nonReentrant isProduct(product) @@ -54,19 +54,20 @@ contract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, URe ProgramInfoLib.validate(programInfo); // Take fee - (ProgramInfo memory newProgramInfo, UFixed18 programFeeAmount) = ProgramInfoLib.deductFee(programInfo, _controller.incentivizationFee()); - fees[newProgramInfo.token] = fees[newProgramInfo.token].add(programFeeAmount); + UFixed18 programTotal = programInfo.amount.sum(); + UFixed18 programFeeAmount = programInfo.deductFee(_controller.incentivizationFee()); + fees[programInfo.token] = fees[programInfo.token].add(programFeeAmount); // Register program - programId = _products[product].register(newProgramInfo); + programId = _products[product].register(programInfo); // Charge creator - newProgramInfo.token.pull(msg.sender, programInfo.amount.sum()); + programInfo.token.pull(msg.sender, programTotal); emit ProgramCreated( product, programId, - newProgramInfo, + programInfo, programFeeAmount ); } diff --git a/packages/perennial/contracts/interfaces/types/ProgramInfo.sol b/packages/perennial/contracts/interfaces/types/ProgramInfo.sol index 19f2e600..fa0b172d 100644 --- a/packages/perennial/contracts/interfaces/types/ProgramInfo.sol +++ b/packages/perennial/contracts/interfaces/types/ProgramInfo.sol @@ -54,17 +54,17 @@ library ProgramInfoLib { /** * @notice Computes a new program info with the fee taken out of the amount - * @param programInfo Original program info + * @dev Modifies the passed in programInfo + * @param programInfo Program info * @param incentivizationFee The incentivization fee - * @return New program info * @return Fee amount */ function deductFee(ProgramInfo memory programInfo, UFixed18 incentivizationFee) - internal pure returns (ProgramInfo memory, UFixed18) { + internal pure returns (UFixed18) { Position memory newProgramAmount = programInfo.amount.mul(UFixed18Lib.ONE.sub(incentivizationFee)); UFixed18 programFeeAmount = programInfo.amount.sub(newProgramAmount).sum(); programInfo.amount = newProgramAmount; - return (programInfo, programFeeAmount); + return programFeeAmount; } /** From b6d83803b13fcde48fa91b3019a2d0cda2d8c707 Mon Sep 17 00:00:00 2001 From: arjun-io <2940142+arjun-io@users.noreply.github.com> Date: Tue, 16 May 2023 10:44:15 -0400 Subject: [PATCH 24/25] Upgrade Core/Vault Solidity Versions (#185) --- packages/common/hardhat.default.config.ts | 2 +- packages/perennial-examples/contracts/examples/Squeeth.sol | 2 +- packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol | 2 +- packages/perennial-oracle/contracts/ChainlinkOracle.sol | 2 +- .../contracts/test/PassthroughChainlinkFeed.sol | 2 +- .../perennial-oracle/contracts/test/PassthroughDataFeed.sol | 2 +- .../contracts/test/TestnetChainlinkFeedRegistry.sol | 2 +- packages/perennial-oracle/contracts/types/ChainlinkRegistry.sol | 2 +- packages/perennial-oracle/contracts/types/ChainlinkRound.sol | 2 +- packages/perennial-vaults/hardhat.config.ts | 1 - packages/perennial/contracts/collateral/Collateral.sol | 2 +- packages/perennial/contracts/controller/Controller.sol | 2 +- packages/perennial/contracts/incentivizer/Incentivizer.sol | 2 +- packages/perennial/contracts/multiinvoker/MultiInvoker.sol | 2 +- .../perennial/contracts/multiinvoker/MultiInvokerRollup.sol | 2 +- 15 files changed, 14 insertions(+), 15 deletions(-) diff --git a/packages/common/hardhat.default.config.ts b/packages/common/hardhat.default.config.ts index ee272457..6897fdf6 100644 --- a/packages/common/hardhat.default.config.ts +++ b/packages/common/hardhat.default.config.ts @@ -17,7 +17,7 @@ import 'hardhat-deploy' import 'hardhat-dependency-compiler' import { getChainId, isArbitrum, isBase, isOptimism, SupportedChain } from './testutil/network' -export const SOLIDITY_VERSION = '0.8.15' +export const SOLIDITY_VERSION = '0.8.17' const PRIVATE_KEY_MAINNET = process.env.PRIVATE_KEY || '' const PRIVATE_KEY_TESTNET = process.env.PRIVATE_KEY_TESTNET || '' diff --git a/packages/perennial-examples/contracts/examples/Squeeth.sol b/packages/perennial-examples/contracts/examples/Squeeth.sol index 4d69674c..b19f1d57 100644 --- a/packages/perennial-examples/contracts/examples/Squeeth.sol +++ b/packages/perennial-examples/contracts/examples/Squeeth.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@equilibria/perennial/contracts/interfaces/IContractPayoffProvider.sol"; diff --git a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol index 4eb7b989..8862c179 100644 --- a/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkFeedOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@openzeppelin/contracts/utils/math/SafeCast.sol"; import "./interfaces/IOracleProvider.sol"; diff --git a/packages/perennial-oracle/contracts/ChainlinkOracle.sol b/packages/perennial-oracle/contracts/ChainlinkOracle.sol index 8d6d36b6..bdd5e534 100644 --- a/packages/perennial-oracle/contracts/ChainlinkOracle.sol +++ b/packages/perennial-oracle/contracts/ChainlinkOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol"; import "@openzeppelin/contracts/utils/math/SafeCast.sol"; diff --git a/packages/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol b/packages/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol index cab676f3..99402985 100644 --- a/packages/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol +++ b/packages/perennial-oracle/contracts/test/PassthroughChainlinkFeed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol"; diff --git a/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol b/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol index 12f7e4a5..53da3cce 100644 --- a/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol +++ b/packages/perennial-oracle/contracts/test/PassthroughDataFeed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; diff --git a/packages/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol b/packages/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol index bf15d1d5..a920f92b 100644 --- a/packages/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol +++ b/packages/perennial-oracle/contracts/test/TestnetChainlinkFeedRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; contract TestnetChainlinkFeedRegistry { mapping(address => mapping(address => uint8)) public decimals; diff --git a/packages/perennial-oracle/contracts/types/ChainlinkRegistry.sol b/packages/perennial-oracle/contracts/types/ChainlinkRegistry.sol index 207d136c..8317bb70 100644 --- a/packages/perennial-oracle/contracts/types/ChainlinkRegistry.sol +++ b/packages/perennial-oracle/contracts/types/ChainlinkRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol"; import "./ChainlinkRound.sol"; diff --git a/packages/perennial-oracle/contracts/types/ChainlinkRound.sol b/packages/perennial-oracle/contracts/types/ChainlinkRound.sol index afa078c5..8334947d 100644 --- a/packages/perennial-oracle/contracts/types/ChainlinkRound.sol +++ b/packages/perennial-oracle/contracts/types/ChainlinkRound.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity ^0.8.15; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; diff --git a/packages/perennial-vaults/hardhat.config.ts b/packages/perennial-vaults/hardhat.config.ts index cadf2315..b581147b 100644 --- a/packages/perennial-vaults/hardhat.config.ts +++ b/packages/perennial-vaults/hardhat.config.ts @@ -33,7 +33,6 @@ const MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES = { } const config = defaultConfig({ - solidityVersion: '0.8.15', solidityOverrides: { 'contracts/balanced/BalancedVault.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, 'contracts/balanced/BalancedVaultDefinition.sol': MINIMUM_CONTRACT_SIZE_SOLIDITY_OVERRIDES, diff --git a/packages/perennial/contracts/collateral/Collateral.sol b/packages/perennial/contracts/collateral/Collateral.sol index d73532bc..10bc225e 100644 --- a/packages/perennial/contracts/collateral/Collateral.sol +++ b/packages/perennial/contracts/collateral/Collateral.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity 0.8.17; import "@equilibria/root/control/unstructured/UInitializable.sol"; import "@equilibria/root/control/unstructured/UReentrancyGuard.sol"; diff --git a/packages/perennial/contracts/controller/Controller.sol b/packages/perennial/contracts/controller/Controller.sol index 3eeff885..62e2e866 100644 --- a/packages/perennial/contracts/controller/Controller.sol +++ b/packages/perennial/contracts/controller/Controller.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity 0.8.17; import "@equilibria/root/control/unstructured/UInitializable.sol"; import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; diff --git a/packages/perennial/contracts/incentivizer/Incentivizer.sol b/packages/perennial/contracts/incentivizer/Incentivizer.sol index 89b5f41b..3a2a6032 100644 --- a/packages/perennial/contracts/incentivizer/Incentivizer.sol +++ b/packages/perennial/contracts/incentivizer/Incentivizer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity 0.8.17; import "@equilibria/root/control/unstructured/UInitializable.sol"; import "@equilibria/root/control/unstructured/UReentrancyGuard.sol"; diff --git a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol index 218eb28c..8823bea0 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvoker.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvoker.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.15; +pragma solidity 0.8.17; import "@equilibria/root/control/unstructured/UInitializable.sol"; diff --git a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol index f560c4ba..4dea9728 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -pragma solidity 0.8.15; +pragma solidity 0.8.17; import "./MultiInvoker.sol"; import "../interfaces/IMultiInvokerRollup.sol"; From dba7e8a92c1b41aca127770d57483d0832db60e8 Mon Sep 17 00:00:00 2001 From: test9955667 <79500129+test9955667@users.noreply.github.com> Date: Wed, 17 May 2023 11:18:57 -0400 Subject: [PATCH 25/25] Nose/fix rollup audit (#183) * convert to action enum * cheaper calldata allocation * magic collision byte * compiler destructuring fix * enforce 1 byte fallback sig * fix previous commit * minor fixes * changs magic byte + add collision assertions * enforce and test invoke id byte --- .../interfaces/IMultiInvokerRollup.sol | 1 + .../multiinvoker/MultiInvokerRollup.sol | 154 +++++++++++------- .../multiinvoker/multiInvokerRollup.test.ts | 68 ++++---- .../multiinvoker/MultiInvokerRollup.test.ts | 106 ++++++------ packages/perennial/test/util.ts | 63 +++++-- 5 files changed, 227 insertions(+), 165 deletions(-) diff --git a/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol b/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol index 0ce564c7..303f34c9 100644 --- a/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol +++ b/packages/perennial/contracts/interfaces/IMultiInvokerRollup.sol @@ -12,6 +12,7 @@ interface IMultiInvokerRollup is IMultiInvoker { error MultiInvokerRollupAddressIndexOutOfBoundsError(); error MultiInvokerRollupInvalidUint256LengthError(); + error MultiInvokerRollupMissingMagicByteError(); function addressCache(uint256 index) external view returns(address); function addressLookup(address value) external view returns(uint256 index); diff --git a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol index 4dea9728..8650237d 100644 --- a/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol +++ b/packages/perennial/contracts/multiinvoker/MultiInvokerRollup.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.17; import "./MultiInvoker.sol"; import "../interfaces/IMultiInvokerRollup.sol"; + /** * @title MultiInvokerRollup * @notice A calldata-optimized implementation of the Perennial MultiInvoker @@ -41,6 +42,10 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { /// @dev Index lookup of above array for constructing calldata mapping(address => uint256) public addressLookup; + /// @dev magic byte to prepend to calldata for the fallback. + /// Prevents public fns from being called by arbitrary fallback data + uint8 public constant INVOKE_ID = 73; + /** * @notice Constructs the contract * @param usdc_ The USDC token contract address @@ -57,12 +62,15 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { /** * @notice This function serves exactly the same as invoke(Invocation[] memory invocations), * but includes logic to handle the highly packed calldata - * @dev Fallback eliminates the need to include function sig in calldata + * @dev Fallback eliminates need for 4 byte sig. MUST prepend INVOKE_ID to calldata * @param input Packed data to pass to invoke logic * @return required no-op */ fallback (bytes calldata input) external returns (bytes memory) { - _decodeFallbackAndInvoke(input); + PTR memory ptr; + if (_readUint8(input, ptr) != INVOKE_ID) revert MultiInvokerRollupMissingMagicByteError(); + + _decodeFallbackAndInvoke(input, ptr); return ""; } @@ -75,81 +83,112 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { * [2:length] => current encoded type (see individual type decoding functions) * @param input Packed data to pass to invoke logic */ - function _decodeFallbackAndInvoke(bytes calldata input) internal { - PTR memory ptr; + function _decodeFallbackAndInvoke(bytes calldata input, PTR memory ptr) internal { while (ptr.pos < input.length) { - uint8 action = _readUint8(input, ptr); + PerennialAction action = PerennialAction(_readUint8(input, ptr)); + + if (action == PerennialAction.DEPOSIT) { + address account = _readAndCacheAddress(input, ptr); + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); - if (action == 1) { // DEPOSIT - (address account, address product, UFixed18 amount) = - (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); _deposit(account, IProduct(product), amount); - } else if (action == 2) { // WITHDRAW - (address receiver, address product, UFixed18 amount) = - (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.WITHDRAW) { + address receiver = _readAndCacheAddress(input, ptr); + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _withdraw(receiver, IProduct(product), amount); - } else if (action == 3) { // OPEN_TAKE - (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.OPEN_TAKE) { + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _openTake(IProduct(product), amount); - } else if (action == 4) { // CLOSE_TAKE - (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.CLOSE_TAKE) { + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _closeTake(IProduct(product), amount); - } else if (action == 5) { // OPEN_MAKE - (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.OPEN_MAKE) { + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _openMake(IProduct(product), amount); - } else if (action == 6) { // CLOSE_MAKE - (address product, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.CLOSE_MAKE) { + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _closeMake(IProduct(product), amount); - } else if (action == 7) { // CLAIM - (address product, uint256[] memory programIds) = - (_readAndCacheAddress(input, ptr), _readUint256Array(input, ptr)); + } else if (action == PerennialAction.CLAIM) { + address product = _readAndCacheAddress(input, ptr); + uint256[] memory programIds = _readUint256Array(input, ptr); + _claim(IProduct(product), programIds); - } else if (action == 8) { // WRAP - (address receiver, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.WRAP) { + address receiver = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _wrap(receiver, amount); - } else if (action == 9) { // UNWRAP - (address receiver, UFixed18 amount) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.UNWRAP) { + address receiver = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _unwrap(receiver, amount); - } else if (action == 10) { // WRAP_AND_DEPOSIT - (address account, address product, UFixed18 amount) = - (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.WRAP_AND_DEPOSIT) { + address account = _readAndCacheAddress(input, ptr); + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _wrapAndDeposit(account, IProduct(product), amount); - } else if (action == 11) { // WITHDRAW_AND_UNWRAP - (address receiver, address product, UFixed18 amount) = - (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.WITHDRAW_AND_UNWRAP) { + address receiver = _readAndCacheAddress(input, ptr); + address product = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _withdrawAndUnwrap(receiver, IProduct(product), amount); - } else if (action == 12) { // VAULT_DEPOSIT - (address depositer, address vault, UFixed18 amount) = - (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.VAULT_DEPOSIT) { + address depositer = _readAndCacheAddress(input, ptr); + address vault = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _vaultDeposit(depositer, IPerennialVault(vault), amount); - } else if (action == 13) { // VAULT_REDEEM - (address vault, UFixed18 shares) = (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.VAULT_REDEEM) { + address vault = _readAndCacheAddress(input, ptr); + UFixed18 shares = _readUFixed18(input, ptr); + _vaultRedeem(IPerennialVault(vault), shares); - } else if (action == 14) { // VAULT_CLAIM - (address owner, address vault) = (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr)); + } else if (action == PerennialAction.VAULT_CLAIM) { + address owner = _readAndCacheAddress(input, ptr); + address vault = _readAndCacheAddress(input, ptr); + _vaultClaim(IPerennialVault(vault), owner); - } else if (action == 15) { // VAULT_WRAP_AND_DEPOSIT - (address account, address vault, UFixed18 amount) = - (_readAndCacheAddress(input, ptr), _readAndCacheAddress(input, ptr), _readUFixed18(input, ptr)); + } else if (action == PerennialAction.VAULT_WRAP_AND_DEPOSIT) { + address account = _readAndCacheAddress(input, ptr); + address vault = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + _vaultWrapAndDeposit(account, IPerennialVault(vault), amount); - } else if (action == 16) { // CHARGE_FEE - (address receiver, UFixed18 amount, bool wrapped) = - (_readAndCacheAddress(input, ptr), _readUFixed18(input, ptr), _readBool(input, ptr)); + + } else if (action == PerennialAction.CHARGE_FEE) { + address receiver = _readAndCacheAddress(input, ptr); + UFixed18 amount = _readUFixed18(input, ptr); + bool wrapped = _readBool(input, ptr); + _chargeFee(receiver, amount, wrapped); } } @@ -183,7 +222,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { _cacheAddress(result); } else { - uint256 idx = _bytesToUint256(input[ptr.pos:ptr.pos + len]); + uint256 idx = _bytesToUint256(input, ptr.pos, len); ptr.pos += len; result = _lookupAddress(idx); @@ -244,7 +283,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { * @return result The decoded uint8 length */ function _readUint8(bytes calldata input, PTR memory ptr) private pure returns (uint8 result) { - result = _bytesToUint8(input[ptr.pos:ptr.pos + UINT8_LENGTH]); + result = _bytesToUint8(input, ptr.pos); ptr.pos += UINT8_LENGTH; } @@ -258,7 +297,7 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { uint8 len = _readUint8(input, ptr); if (len > UINT256_LENGTH) revert MultiInvokerRollupInvalidUint256LengthError(); - result = _bytesToUint256(input[ptr.pos:ptr.pos + len]); + result = _bytesToUint256(input, ptr.pos, len); ptr.pos += len; } @@ -267,9 +306,12 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { * @param input 1 byte slice to convert to uint8 to decode lengths * @return result The uint8 representation of input */ - function _bytesToUint8(bytes memory input) private pure returns (uint8 result) { + function _bytesToUint8(bytes calldata input, uint256 pos) private pure returns (uint8 result) { assembly { - result := mload(add(input, UINT8_LENGTH)) + // 1) load calldata into temp starting at ptr position + let temp := calldataload(add(input.offset, pos)) + // 2) shifts the calldata such that only the first byte is stored in result + result := shr(mul(8, sub(UINT256_LENGTH, UINT8_LENGTH)), temp) } } @@ -291,14 +333,12 @@ contract MultiInvokerRollup is IMultiInvokerRollup, MultiInvoker { * @param input The bytes to convert to uint256 * @return result The resulting uint256 */ - function _bytesToUint256(bytes memory input) private pure returns (uint256 result) { - uint256 len = input.length; - + function _bytesToUint256(bytes calldata input, uint256 pos, uint256 len) private pure returns (uint256 result) { assembly { - result := mload(add(input, UINT256_LENGTH)) + // 1) load the calldata into result starting at the ptr position + result := calldataload(add(input.offset, pos)) + // 2) shifts the calldata such that only the next length of bytes specified by `len` populates the uint256 result + result := shr(mul(8, sub(UINT256_LENGTH, len)), result) } - - // readable right shift to change right padding of mload to left padding - result >>= (UINT256_LENGTH - len) * 8; } } diff --git a/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts b/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts index 42f135f9..2ef6978c 100644 --- a/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts +++ b/packages/perennial/test/integration/multiinvoker/multiInvokerRollup.test.ts @@ -148,9 +148,7 @@ describe('MultiInvokerRollup', () => { await usdc.connect(usdcHolder).transfer(user.address, 1_000_000e6) await expect( - await user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + customActions.WRAP.payload), - ), + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, customActions.WRAP.payload)), ) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 2_000_000e6) @@ -167,7 +165,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_MAKE])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 10000e6) .to.emit(batcher, 'Wrap') @@ -183,7 +181,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.WRAP_AND_DEPOSIT, actions.OPEN_MAKE])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 10000e6) .to.emit(batcher, 'Wrap') @@ -199,7 +197,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.DEPOSIT, actions.OPEN_MAKE])) - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload)) await expect(res) .to.emit(collateral, 'Deposit') @@ -213,7 +211,7 @@ describe('MultiInvokerRollup', () => { const payload1 = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_MAKE])) - const res1 = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload1)) + const res1 = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload1)) await expect(res1).to.not.be.reverted await depositTo(instanceVars, userB, product, amount) @@ -233,7 +231,7 @@ describe('MultiInvokerRollup', () => { Object.values([partialActions.CLOSE_MAKE, partialActions.WITHDRAW, actions.CLAIM]), ) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload2))) .to.emit(product, 'MakeClosed') .withArgs(user.address, INITIAL_VERSION + 4, position.div(2)) .to.emit(collateral, 'Withdrawal') @@ -247,13 +245,13 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_MAKE])) - await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload)) await chainlink.next() const payload2 = buildAllActionsRollup(Object.values([partialActions.CLOSE_MAKE, partialActions.DEPOSIT])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload2))) .to.emit(product, 'MakeClosed') .withArgs(user.address, INITIAL_VERSION + 1, position.div(2)) .to.emit(collateral, 'Deposit') @@ -268,7 +266,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_TAKE])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 10000e6) .to.emit(batcher, 'Wrap') @@ -287,7 +285,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.WRAP_AND_DEPOSIT, actions.OPEN_TAKE])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 10000e6) .to.emit(batcher, 'Wrap') @@ -306,7 +304,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.DEPOSIT, actions.OPEN_TAKE])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(collateral, 'Deposit') .withArgs(user.address, product.address, amount) .to.emit(product, 'TakeOpened') @@ -320,13 +318,13 @@ describe('MultiInvokerRollup', () => { await product.connect(userB).openMake(position) const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_TAKE])) - await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload)) await chainlink.next() const payload2 = buildAllActionsRollup(Object.values([partialActions.CLOSE_TAKE, partialActions.DEPOSIT])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload2))) .to.emit(product, 'TakeClosed') .withArgs(user.address, INITIAL_VERSION + 1, position.div(2)) .to.emit(collateral, 'Deposit') @@ -340,7 +338,7 @@ describe('MultiInvokerRollup', () => { await product.connect(userB).openMake(position) const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.DEPOSIT, actions.OPEN_TAKE])) - await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload)) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload)) await chainlink.next() await product.settle() @@ -354,7 +352,7 @@ describe('MultiInvokerRollup', () => { Object.values([partialActions.CLOSE_TAKE, partialActions.WITHDRAW, actions.CLAIM]), ) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload2))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload2))) .to.emit(product, 'TakeClosed') .withArgs(user.address, INITIAL_VERSION + 4, position.div(2)) .to.emit(collateral, 'Withdrawal') @@ -372,10 +370,10 @@ describe('MultiInvokerRollup', () => { await batcher.rebalance() // Deposit the collateral to withdraw - await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload)) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.DEPOSIT.payload)) const payload = buildAllActionsRollup(Object.values([actions.WITHDRAW, actions.UNWRAP])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(collateral, 'Withdrawal') .withArgs(user.address, product.address, amount) .to.emit(reserve, 'Redeem') @@ -395,7 +393,7 @@ describe('MultiInvokerRollup', () => { buildTransactionRequest( user, multiInvokerRollup, - `0x` + actions.WRAP.payload + customActions.CHARGE_FEE.payload, + actions.WRAP.payload + customActions.CHARGE_FEE.payload.substring(4), ), ) @@ -407,9 +405,7 @@ describe('MultiInvokerRollup', () => { it(`wraps USDC to DSU on WRAP action and invokes CHARGE_FEE to interface `, async () => { const { user, multiInvokerRollup, usdc, dsu } = instanceVars - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CHARGE_FEE.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.CHARGE_FEE.payload)) await expect(res).to.not.be.reverted expect(await dsu.balanceOf(vault.address)).to.eq(utils.parseEther('10')) @@ -424,12 +420,10 @@ describe('MultiInvokerRollup', () => { await batcher.rebalance() // Deposit the collateral to withdraw - await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload)) + await user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.DEPOSIT.payload)) await expect( - user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW_AND_UNWRAP.payload), - ), + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.WITHDRAW_AND_UNWRAP.payload)), ) .to.emit(collateral, 'Withdrawal') .withArgs(user.address, product.address, amount) @@ -453,9 +447,7 @@ describe('MultiInvokerRollup', () => { data: twowayiface.encodeFunctionData('deposit', [utils.parseEther('20000')]), }) - await expect( - user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)), - ) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.UNWRAP.payload))) .to.emit(batcher, 'Unwrap') .withArgs(user.address, amount) .to.emit(usdc, 'Transfer') @@ -467,7 +459,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.WRAP, actions.VAULT_DEPOSIT])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(batcher, 'Wrap') .withArgs(user.address, amount) .to.emit(dsu, 'Transfer') @@ -486,7 +478,7 @@ describe('MultiInvokerRollup', () => { const payload = buildAllActionsRollup(Object.values([actions.VAULT_DEPOSIT, actions.VAULT_REDEEM])) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(vault, 'Redemption') .withArgs(multiInvokerRollup.address, user.address, 1, vaultAmount) @@ -501,7 +493,7 @@ describe('MultiInvokerRollup', () => { Object.values([actions.VAULT_DEPOSIT, actions.VAULT_REDEEM, actions.VAULT_CLAIM, actions.UNWRAP]), ) - await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + payload))) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, payload))) .to.emit(dsu, 'Transfer') .withArgs(vault.address, user.address, vaultAmount) .to.emit(vault, 'Claim') @@ -517,9 +509,7 @@ describe('MultiInvokerRollup', () => { const { user, multiInvokerRollup, dsu, usdc, batcher } = instanceVars await expect( - user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_WRAP_AND_DEPOSIT.payload), - ), + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.VAULT_WRAP_AND_DEPOSIT.payload)), ) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 10000e6) @@ -553,7 +543,7 @@ describe('MultiInvokerRollup', () => { await usdc.connect(usdcHolder).transfer(user.address, 1_000_000e6) await expect( - user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + customActions.WRAP.payload)), + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, customActions.WRAP.payload)), ) .to.emit(usdc, 'Transfer') .withArgs(user.address, multiInvokerRollup.address, 2_000_000e6) @@ -573,9 +563,7 @@ describe('MultiInvokerRollup', () => { await batcher.connect(user).wrap(amount, user.address) await batcher.rebalance() - await expect( - user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)), - ) + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.UNWRAP.payload))) .to.emit(reserve, 'Redeem') .withArgs(multiInvokerRollup.address, amount, 10000e6) .to.emit(usdc, 'Transfer') diff --git a/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts b/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts index 2ab25a40..e90f082c 100644 --- a/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts +++ b/packages/perennial/test/unit/multiinvoker/MultiInvokerRollup.test.ts @@ -17,8 +17,9 @@ import { TestnetVault, } from '../../../types/generated' import { IMultiInvokerRollup } from '../../../types/generated/contracts/interfaces/IMultiInvokerRollup' -import { InvokerAction, buildInvokerActionRollup, buildAllActionsRollup } from '../../util' +import { InvokerAction, buildInvokerActionRollup, buildAllActionsRollup, MAGIC_BYTE } from '../../util' import { TransactionRequest } from '@ethersproject/abstract-provider' +import { multiinvoker } from '../../../types/generated/contracts' const { ethers } = HRE use(smock.matchers) @@ -87,6 +88,21 @@ describe('MultiInvokerRollup', () => { await multiInvokerRollup.initialize() }) + describe('#invoke_id', () => { + it(`magic byte header ${MAGIC_BYTE} does not collide with existing fns`, () => { + const sigs: string[] = Object.keys(multiInvokerRollup.functions) + .filter(i => i.endsWith(')')) + .map(v => ethers.utils.id(v)) + sigs.forEach(v => { + expect(v.startsWith(MAGIC_BYTE)).to.eq(false) + }) + }) + + it(`magic byte invoke id publicly accessible`, async () => { + expect(await multiInvokerRollup.connect(user).callStatic.INVOKE_ID()).to.eq(73) + }) + }) + describe('#constructor', () => { it('constructs correctly', async () => { expect((await multiInvokerRollup.USDC()).toLowerCase()).to.equal(usdc.address.toLowerCase()) @@ -169,37 +185,38 @@ describe('MultiInvokerRollup', () => { // store product in cache await expect( - user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), - ), + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.WRAP_AND_DEPOSIT.payload)), ).to.not.be.reverted // cache index 3 is out of bounds, expect panic - const badAddressCachePld = '0x030103' + const badAddressCachePld = '0x49030103' await expect( user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, badAddressCachePld)), ).to.be.revertedWithPanic() // length > 32 (33) for uint error - const badAmountPld = '0x030101213452434344' + const badAmountPld = '0x49030101213452434344' await expect( user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, badAmountPld)), ).to.be.revertedWithCustomError(multiInvokerRollup, 'MultiInvokerRollupInvalidUint256LengthError') + + await expect( + user.sendTransaction( + buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload.substring(4)), + ), + ).to.be.revertedWithCustomError(multiInvokerRollup, 'MultiInvokerRollupMissingMagicByteError') }) it(`decodes 0 as a value on any action`, async () => { usdc.transferFrom.whenCalledWith(user.address, multiInvokerRollup.address, 0).returns(true) - await expect( - user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + zeroAction.WRAP.payload)), - ).to.not.be.reverted + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, zeroAction.WRAP.payload))).to + .not.be.reverted expect(batcher.wrap).to.have.been.calledWith(BigNumber.from(0), user.address) }) it('deposits on DEPOSIT action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.DEPOSIT.payload)) await expect(res).to.not.be.reverted expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) @@ -207,59 +224,49 @@ describe('MultiInvokerRollup', () => { }) it('withdraws on WITHDRAW action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.WITHDRAW.payload)) await expect(res).to.not.be.reverted expect(collateral.withdrawFrom).to.have.been.calledWith(user.address, user.address, product.address, amount) }) it('opens a take position on OPEN_TAKE action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.OPEN_TAKE.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.OPEN_TAKE.payload)) await expect(res).to.not.be.reverted expect(product.openTakeFor).to.have.been.calledWith(user.address, position) }) it('closes a take position on CLOSE_TAKE action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CLOSE_TAKE.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.CLOSE_TAKE.payload)) await expect(res).to.not.be.reverted expect(product.closeTakeFor).to.have.been.calledWith(user.address, position) }) it('opens a make position on OPEN_MAKE action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.OPEN_MAKE.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.OPEN_MAKE.payload)) await expect(res).to.not.be.reverted expect(product.openMakeFor).to.have.been.calledWith(user.address, position) }) it('closes a make position on CLOSE_MAKE action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CLOSE_MAKE.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.CLOSE_MAKE.payload)) await expect(res).to.not.be.reverted expect(product.closeMakeFor).to.have.been.calledWith(user.address, position) }) it('claims incentive rewards on CLAIM action', async () => { - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.CLAIM.payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.CLAIM.payload)) await expect(res).to.not.be.reverted expect(incentivizer.claimFor).to.have.been.calledWith(user.address, product.address, programs) }) it('wraps USDC to DSU on WRAP action', async () => { - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP.payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.WRAP.payload)) await expect(res).to.not.be.reverted expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) @@ -270,7 +277,7 @@ describe('MultiInvokerRollup', () => { dsu.balanceOf.whenCalledWith(batcher.address).returns(0) dsu.transfer.whenCalledWith(user.address, amount).returns(true) - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP.payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.WRAP.payload)) await expect(res).to.not.be.reverted expect(usdc.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, usdcAmount) @@ -279,7 +286,7 @@ describe('MultiInvokerRollup', () => { }) it('unwraps DSU to USDC on UNWRAP action', async () => { - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.UNWRAP.payload)) await expect(res).to.not.be.reverted expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) @@ -290,7 +297,7 @@ describe('MultiInvokerRollup', () => { usdc.balanceOf.whenCalledWith(batcher.address).returns(0) usdc.transfer.whenCalledWith(user.address, amount).returns(true) - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.UNWRAP.payload)) await expect(res).to.not.be.reverted expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) @@ -300,7 +307,7 @@ describe('MultiInvokerRollup', () => { it('wraps USDC to DSU then deposits DSU on WRAP_AND_DEPOSIT action', async () => { const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), + buildTransactionRequest(user, multiInvokerRollup, actions.WRAP_AND_DEPOSIT.payload), ) await expect(res).to.not.be.reverted @@ -314,7 +321,7 @@ describe('MultiInvokerRollup', () => { dsu.transfer.whenCalledWith(multiInvokerRollup.address, amount).returns(true) const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP_AND_DEPOSIT.payload), + buildTransactionRequest(user, multiInvokerRollup, actions.WRAP_AND_DEPOSIT.payload), ) await expect(res).to.not.be.reverted @@ -325,7 +332,7 @@ describe('MultiInvokerRollup', () => { it('withdraws then unwraps DSU to USDC on WITHDRAW_AND_UNWRAP action', async () => { const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW_AND_UNWRAP.payload), + buildTransactionRequest(user, multiInvokerRollup, actions.WITHDRAW_AND_UNWRAP.payload), ) await expect(res).to.not.be.reverted @@ -343,7 +350,7 @@ describe('MultiInvokerRollup', () => { usdc.balanceOf.whenCalledWith(batcher.address).returns(0) const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WITHDRAW_AND_UNWRAP.payload), + buildTransactionRequest(user, multiInvokerRollup, actions.WITHDRAW_AND_UNWRAP.payload), ) await expect(res).to.not.be.reverted @@ -358,9 +365,7 @@ describe('MultiInvokerRollup', () => { }) it('deposits to vault on VAULT_DEPOSIT action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_DEPOSIT.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.VAULT_DEPOSIT.payload)) await expect(res).to.not.be.reverted expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, vaultAmount) @@ -369,18 +374,14 @@ describe('MultiInvokerRollup', () => { }) it('redeems from vault on VAULT_REDEEM action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_REDEEM.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.VAULT_REDEEM.payload)) await expect(res).to.not.be.reverted expect(vault.redeem).to.have.been.calledWith(vaultAmount, user.address) }) it('claims from vault on VAULT_CLAIM action', async () => { - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_CLAIM.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.VAULT_CLAIM.payload)) await expect(res).to.not.be.reverted expect(vault.claim).to.have.been.calledWith(user.address) @@ -388,7 +389,7 @@ describe('MultiInvokerRollup', () => { it('wraps USDC to DSU then deposits DSU to the vault on VAULT_WRAP_AND_DEPOSIT action', async () => { const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.VAULT_WRAP_AND_DEPOSIT.payload), + buildTransactionRequest(user, multiInvokerRollup, actions.VAULT_WRAP_AND_DEPOSIT.payload), ) await expect(res).to.not.be.reverted @@ -516,7 +517,7 @@ describe('MultiInvokerRollup', () => { it('wraps USDC to DSU using RESERVE on WRAP action', async () => { dsu.transfer.whenCalledWith(user.address, amount).returns(true) - const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.WRAP.payload)) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.WRAP.payload)) await expect(res).to.not.be.reverted // multiInvokerRollup.connect(user).invoke([actions.WRAP]) @@ -528,9 +529,7 @@ describe('MultiInvokerRollup', () => { it('unwraps DSU to USDC using RESERVE on UNWRAP action', async () => { usdc.transfer.whenCalledWith(user.address, amount).returns(true) - const res = user.sendTransaction( - buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.UNWRAP.payload), - ) + const res = user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.UNWRAP.payload)) await expect(res).to.not.be.reverted @@ -611,9 +610,8 @@ describe('MultiInvokerRollup', () => { it('performs cached invoke on DEPOSIT', async () => { // 1) set state caching - await expect( - user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actions.DEPOSIT.payload)), - ).to.not.be.reverted + await expect(user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actions.DEPOSIT.payload))) + .to.not.be.reverted expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) @@ -624,7 +622,7 @@ describe('MultiInvokerRollup', () => { // 2) call contract with cached payload await expect( - user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, '0x' + actionsCached.DEPOSIT.payload)), + user.sendTransaction(buildTransactionRequest(user, multiInvokerRollup, actionsCached.DEPOSIT.payload)), ).to.not.be.reverted expect(dsu.transferFrom).to.have.been.calledWith(user.address, multiInvokerRollup.address, amount) expect(collateral.depositTo).to.have.been.calledWith(user.address, product.address, amount) diff --git a/packages/perennial/test/util.ts b/packages/perennial/test/util.ts index 2d2602ea..3e84ebfe 100644 --- a/packages/perennial/test/util.ts +++ b/packages/perennial/test/util.ts @@ -2,6 +2,8 @@ import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' import { constants, utils, BigNumberish, BigNumber } from 'ethers' import { IMultiInvoker, MultiInvokerRollup } from '../types/generated' +export const MAGIC_BYTE = '0x49' + export type InvokerAction = | 'NOOP' | 'DEPOSIT' @@ -130,14 +132,14 @@ export const buildAllActionsRollup = ( // programs?: number[] // }[] ): string => { - let pld = '' + let pld = MAGIC_BYTE for (const a of actions) { - if (a.action == 'NOOP') { + if (a.payload == MAGIC_BYTE) { continue } - - pld += a.payload + // remove magic byte from each action when multiple actions + pld += a.payload.substring(4) } return pld @@ -160,12 +162,13 @@ export const buildInvokerActionRollup = ( return { NOOP: { action: 0, - payload: '0x', + payload: MAGIC_BYTE, }, DEPOSIT: { action: 1, // [userAddress productAddress amount] payload: + MAGIC_BYTE + '01' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(productCache, productAddress) + @@ -175,6 +178,7 @@ export const buildInvokerActionRollup = ( action: 2, // [userAddress productAddress amount] payload: + MAGIC_BYTE + '02' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(productCache, productAddress) + @@ -183,42 +187,62 @@ export const buildInvokerActionRollup = ( OPEN_TAKE: { action: 3, // [productAddress position] - payload: '03' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + payload: + MAGIC_BYTE + + '03' + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(position)), }, CLOSE_TAKE: { action: 4, // [productAddress position] - payload: '04' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + payload: + MAGIC_BYTE + + '04' + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(position)), }, OPEN_MAKE: { action: 5, // [productAddress position] - payload: '05' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + payload: + MAGIC_BYTE + + '05' + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(position)), }, CLOSE_MAKE: { action: 6, // [productAddress position] - payload: '06' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeUint(BigNumber.from(position)), + payload: + MAGIC_BYTE + + '06' + + encodeAddressOrCacheIndex(productCache, productAddress) + + encodeUint(BigNumber.from(position)), }, CLAIM: { action: 7, // [productAddress programs] - payload: '07' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeProgramIds(programs!), + payload: + MAGIC_BYTE + '07' + encodeAddressOrCacheIndex(productCache, productAddress) + encodeProgramIds(programs!), }, WRAP: { action: 8, // [userAddress amount] - payload: '08' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeUint(BigNumber.from(amount)), + payload: + MAGIC_BYTE + '08' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeUint(BigNumber.from(amount)), }, UNWRAP: { action: 9, // [userAddress amount] - payload: '09' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeUint(BigNumber.from(amount)), + payload: + MAGIC_BYTE + '09' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeUint(BigNumber.from(amount)), }, WRAP_AND_DEPOSIT: { action: 10, // [userAddress, productAddress, amount] payload: + MAGIC_BYTE + '0A' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(productCache, productAddress) + @@ -228,6 +252,7 @@ export const buildInvokerActionRollup = ( action: 11, // [userAddress, productAddress, amount] payload: + MAGIC_BYTE + '0B' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(productCache, productAddress) + @@ -236,6 +261,7 @@ export const buildInvokerActionRollup = ( VAULT_DEPOSIT: { action: 12, payload: + MAGIC_BYTE + '0C' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + @@ -243,16 +269,24 @@ export const buildInvokerActionRollup = ( }, VAULT_REDEEM: { action: 13, - payload: '0D' + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + encodeUint(BigNumber.from(vaultAmount)), + payload: + MAGIC_BYTE + + '0D' + + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + + encodeUint(BigNumber.from(vaultAmount)), }, VAULT_CLAIM: { action: 14, payload: - '0E' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(vaultCache, vaultAddress), + MAGIC_BYTE + + '0E' + + encodeAddressOrCacheIndex(userCache, userAddress) + + encodeAddressOrCacheIndex(vaultCache, vaultAddress), }, VAULT_WRAP_AND_DEPOSIT: { action: 15, payload: + MAGIC_BYTE + '0F' + encodeAddressOrCacheIndex(userCache, userAddress) + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + @@ -261,6 +295,7 @@ export const buildInvokerActionRollup = ( CHARGE_FEE: { action: 16, payload: + MAGIC_BYTE + `10` + encodeAddressOrCacheIndex(vaultCache, vaultAddress) + encodeUint(BigNumber.from(feeAmount)) +